iterator) {
this.iterator = iterator;
}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/QueryEvaluationUtil.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/QueryEvaluationUtil.java
index 9359611a711..45f81051f2e 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/QueryEvaluationUtil.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/QueryEvaluationUtil.java
@@ -20,6 +20,7 @@
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.base.CoreDatatype;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
+import org.eclipse.rdf4j.model.impl.BooleanLiteral;
import org.eclipse.rdf4j.model.util.Literals;
import org.eclipse.rdf4j.query.algebra.Compare.CompareOp;
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
@@ -62,6 +63,13 @@ public class QueryEvaluationUtil {
* @throws ValueExprEvaluationException In case the application of the EBV algorithm results in a type error.
*/
public static boolean getEffectiveBooleanValue(Value value) throws ValueExprEvaluationException {
+
+ if (value == BooleanLiteral.TRUE) {
+ return true;
+ } else if (value == BooleanLiteral.FALSE) {
+ return false;
+ }
+
if (value.isLiteral()) {
Literal literal = (Literal) value;
String label = literal.getLabel();
@@ -107,6 +115,15 @@ public static boolean compare(Value leftVal, Value rightVal, CompareOp operator)
public static boolean compare(Value leftVal, Value rightVal, CompareOp operator, boolean strict)
throws ValueExprEvaluationException {
+ if (leftVal == rightVal) {
+ switch (operator) {
+ case EQ:
+ return true;
+ case NE:
+ return false;
+ }
+ }
+
if (leftVal != null && leftVal.isLiteral() && rightVal != null && rightVal.isLiteral()) {
// Both left and right argument is a Literal
return compareLiterals((Literal) leftVal, (Literal) rightVal, operator, strict);
@@ -162,6 +179,15 @@ public static boolean compareLiterals(Literal leftLit, Literal rightLit, Compare
// - CoreDatatype.XSD:string
// - RDF term (equal and unequal only)
+ if (leftLit == rightLit) {
+ switch (operator) {
+ case EQ:
+ return true;
+ case NE:
+ return false;
+ }
+ }
+
CoreDatatype.XSD leftCoreDatatype = leftLit.getCoreDatatype().asXSDDatatypeOrNull();
CoreDatatype.XSD rightCoreDatatype = rightLit.getCoreDatatype().asXSDDatatypeOrNull();
@@ -329,7 +355,7 @@ && isSupportedDatatype(rightCoreDatatype)) {
* 6.6 Blank Nodes of [CONCEPTS].
*
*
- *
+ *
* (emphasis ours)
*
* When applying the SPARQL specification in a minimally-conforming manner, RDFterm-equal is supposed to return a
@@ -349,7 +375,6 @@ && isSupportedDatatype(rightCoreDatatype)) {
* @param rightCoreDatatype the right datatype to compare
* @throws ValueExprEvaluationException if query evaluation is operating in strict mode, and the two supplied
* datatypes are both supported datatypes but not comparable.
- *
* @see Github issue #3947
*/
private static void validateDatatypeCompatibility(boolean strict, CoreDatatype.XSD leftCoreDatatype,
diff --git a/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIteratorTest.java b/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIteratorTest.java
index 23fa0211849..bdcb5d6abbe 100644
--- a/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIteratorTest.java
+++ b/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIteratorTest.java
@@ -13,13 +13,19 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import java.util.function.Predicate;
+import org.eclipse.rdf4j.common.iteration.LookAheadIteration;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
@@ -29,22 +35,8 @@
import org.eclipse.rdf4j.model.vocabulary.XSD;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryEvaluationException;
-import org.eclipse.rdf4j.query.algebra.AggregateFunctionCall;
-import org.eclipse.rdf4j.query.algebra.Avg;
-import org.eclipse.rdf4j.query.algebra.BindingSetAssignment;
-import org.eclipse.rdf4j.query.algebra.Count;
-import org.eclipse.rdf4j.query.algebra.Group;
-import org.eclipse.rdf4j.query.algebra.GroupConcat;
-import org.eclipse.rdf4j.query.algebra.GroupElem;
-import org.eclipse.rdf4j.query.algebra.MathExpr;
-import org.eclipse.rdf4j.query.algebra.Max;
-import org.eclipse.rdf4j.query.algebra.Min;
-import org.eclipse.rdf4j.query.algebra.Sample;
-import org.eclipse.rdf4j.query.algebra.Sum;
-import org.eclipse.rdf4j.query.algebra.Var;
-import org.eclipse.rdf4j.query.algebra.evaluation.EvaluationStrategy;
-import org.eclipse.rdf4j.query.algebra.evaluation.QueryBindingSet;
-import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
+import org.eclipse.rdf4j.query.algebra.*;
+import org.eclipse.rdf4j.query.algebra.evaluation.*;
import org.eclipse.rdf4j.query.algebra.evaluation.impl.QueryEvaluationContext;
import org.eclipse.rdf4j.query.algebra.evaluation.impl.StrictEvaluationStrategy;
import org.eclipse.rdf4j.query.algebra.evaluation.util.MathUtil;
@@ -260,6 +252,52 @@ public void testCustomAggregateFunction_WrongIri() throws QueryEvaluationExcepti
}
}
+ @Test
+ public void testGroupIteratorClose() throws QueryEvaluationException, InterruptedException {
+ // Lock which is already locked to block the thread driving the iteration
+ Lock lock = new ReentrantLock();
+ lock.lock();
+ // Latch to rendezvous on with the iterating thread
+ CountDownLatch iterating = new CountDownLatch(1);
+ // Latch to record whether the iteration under GroupIterator was closed
+ CountDownLatch closed = new CountDownLatch(1);
+
+ EvaluationStrategy evaluator = new StrictEvaluationStrategy(null, null) {
+ @Override
+ protected QueryEvaluationStep prepare(EmptySet emptySet, QueryEvaluationContext context)
+ throws QueryEvaluationException {
+ return bindings -> new LookAheadIteration<>() {
+ @Override
+ protected BindingSet getNextElement() {
+ iterating.countDown(); // signal to test thread iteration started
+ lock.lock(); // block iterating thread
+ return null;
+ }
+
+ @Override
+ protected void handleClose() {
+ closed.countDown();
+ }
+ };
+ }
+ };
+
+ Group group = new Group(new EmptySet());
+ GroupIterator groupIterator = new GroupIterator(evaluator, group, EmptyBindingSet.getInstance(), context);
+
+ Thread iteratorThread = new Thread(groupIterator::next, "GroupIteratorTest#testGroupIteratorClose");
+ try {
+ iteratorThread.start();
+ assertThat(iterating.await(5, TimeUnit.SECONDS)).isTrue();
+ groupIterator.close();
+ assertThat(closed.await(5, TimeUnit.SECONDS)).isTrue();
+ } finally {
+ lock.unlock();
+ iteratorThread.join(Duration.ofSeconds(5).toMillis());
+ assertThat(iteratorThread.isAlive()).isFalse();
+ }
+ }
+
/**
* Dummy collector to verify custom aggregate functions
*/
diff --git a/core/queryalgebra/geosparql/pom.xml b/core/queryalgebra/geosparql/pom.xml
index 279a38d01f3..4624020fb40 100644
--- a/core/queryalgebra/geosparql/pom.xml
+++ b/core/queryalgebra/geosparql/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryalgebra
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryalgebra-geosparql
RDF4J: Query algebra - GeoSPARQL
diff --git a/core/queryalgebra/model/pom.xml b/core/queryalgebra/model/pom.xml
index b14f3503292..4c7df28ee81 100644
--- a/core/queryalgebra/model/pom.xml
+++ b/core/queryalgebra/model/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryalgebra
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryalgebra-model
RDF4J: Query algebra - model
diff --git a/core/queryalgebra/pom.xml b/core/queryalgebra/pom.xml
index b043f6104c7..b89e1012d31 100644
--- a/core/queryalgebra/pom.xml
+++ b/core/queryalgebra/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-core
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryalgebra
pom
diff --git a/core/queryparser/api/pom.xml b/core/queryparser/api/pom.xml
index a57df203f24..3c8aae2e1b3 100644
--- a/core/queryparser/api/pom.xml
+++ b/core/queryparser/api/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryparser
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryparser-api
RDF4J: Query parser - API
diff --git a/core/queryparser/pom.xml b/core/queryparser/pom.xml
index fed26862f3b..2dad1fcf022 100644
--- a/core/queryparser/pom.xml
+++ b/core/queryparser/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-core
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryparser
pom
diff --git a/core/queryparser/sparql/pom.xml b/core/queryparser/sparql/pom.xml
index 3356aeadcd2..58013a511d0 100644
--- a/core/queryparser/sparql/pom.xml
+++ b/core/queryparser/sparql/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryparser
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryparser-sparql
RDF4J: Query parser - SPARQL
diff --git a/core/queryrender/pom.xml b/core/queryrender/pom.xml
index 22c86d521dd..5c837892ad1 100644
--- a/core/queryrender/pom.xml
+++ b/core/queryrender/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-core
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryrender
RDF4J: Query Rendering
diff --git a/core/queryresultio/api/pom.xml b/core/queryresultio/api/pom.xml
index f1ebf98ff71..c0682af50f0 100644
--- a/core/queryresultio/api/pom.xml
+++ b/core/queryresultio/api/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryresultio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryresultio-api
RDF4J: Query result IO - API
diff --git a/core/queryresultio/binary/pom.xml b/core/queryresultio/binary/pom.xml
index 8f295cfb4c1..9c8f044621c 100644
--- a/core/queryresultio/binary/pom.xml
+++ b/core/queryresultio/binary/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryresultio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryresultio-binary
RDF4J: Query result IO - binary
diff --git a/core/queryresultio/binary/src/main/java/org/eclipse/rdf4j/query/resultio/binary/BinaryQueryResultParser.java b/core/queryresultio/binary/src/main/java/org/eclipse/rdf4j/query/resultio/binary/BinaryQueryResultParser.java
index b256a2198db..5fb8dfc770c 100644
--- a/core/queryresultio/binary/src/main/java/org/eclipse/rdf4j/query/resultio/binary/BinaryQueryResultParser.java
+++ b/core/queryresultio/binary/src/main/java/org/eclipse/rdf4j/query/resultio/binary/BinaryQueryResultParser.java
@@ -227,7 +227,7 @@ private void processError() throws IOException, QueryResultParseException {
} else if (errTypeFlag == QUERY_EVALUATION_ERROR) {
errType = QueryErrorType.QUERY_EVALUATION_ERROR;
} else {
- throw new QueryResultParseException("Unkown error type: " + errTypeFlag);
+ throw new QueryResultParseException("Unknown error type: " + errTypeFlag);
}
String msg = readString();
diff --git a/core/queryresultio/pom.xml b/core/queryresultio/pom.xml
index ce42ffe6eba..5532a815d4c 100644
--- a/core/queryresultio/pom.xml
+++ b/core/queryresultio/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-core
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryresultio
pom
diff --git a/core/queryresultio/sparqljson/pom.xml b/core/queryresultio/sparqljson/pom.xml
index f6f610256d8..da368bfb36e 100644
--- a/core/queryresultio/sparqljson/pom.xml
+++ b/core/queryresultio/sparqljson/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryresultio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryresultio-sparqljson
RDF4J: Query result IO - SPARQL/JSON
diff --git a/core/queryresultio/sparqlxml/pom.xml b/core/queryresultio/sparqlxml/pom.xml
index e9611ee8acb..3e2292024eb 100644
--- a/core/queryresultio/sparqlxml/pom.xml
+++ b/core/queryresultio/sparqlxml/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryresultio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryresultio-sparqlxml
RDF4J: Query result IO - SPARQL/XML
diff --git a/core/queryresultio/text/pom.xml b/core/queryresultio/text/pom.xml
index f3f6877bdaf..3e95d66738e 100644
--- a/core/queryresultio/text/pom.xml
+++ b/core/queryresultio/text/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-queryresultio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-queryresultio-text
RDF4J: Query result IO - plain text booleans
diff --git a/core/repository/api/pom.xml b/core/repository/api/pom.xml
index 7ef6b60860e..5e16576f662 100644
--- a/core/repository/api/pom.xml
+++ b/core/repository/api/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-repository
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository-api
RDF4J: Repository - API
diff --git a/core/repository/contextaware/pom.xml b/core/repository/contextaware/pom.xml
index fcce28e86e1..3ae8aea353f 100644
--- a/core/repository/contextaware/pom.xml
+++ b/core/repository/contextaware/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-repository
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository-contextaware
RDF4J: Repository - context aware (wrapper)
diff --git a/core/repository/dataset/pom.xml b/core/repository/dataset/pom.xml
index d44a04e340c..c601265c72b 100644
--- a/core/repository/dataset/pom.xml
+++ b/core/repository/dataset/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-repository
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository-dataset
RDF4J: DatasetRepository (wrapper)
diff --git a/core/repository/event/pom.xml b/core/repository/event/pom.xml
index b7bb0962319..05dbbc70276 100644
--- a/core/repository/event/pom.xml
+++ b/core/repository/event/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-repository
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository-event
RDF4J: Repository - event (wrapper)
diff --git a/core/repository/http/pom.xml b/core/repository/http/pom.xml
index 9448deaa0f6..2ed36d9acfc 100644
--- a/core/repository/http/pom.xml
+++ b/core/repository/http/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-repository
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository-http
RDF4J: HTTPRepository
diff --git a/core/repository/manager/pom.xml b/core/repository/manager/pom.xml
index ce64f0923ff..56ba4f7066e 100644
--- a/core/repository/manager/pom.xml
+++ b/core/repository/manager/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-repository
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository-manager
RDF4J: Repository manager
diff --git a/core/repository/pom.xml b/core/repository/pom.xml
index a8e503256cf..494eb65b759 100644
--- a/core/repository/pom.xml
+++ b/core/repository/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-core
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository
pom
diff --git a/core/repository/sail/pom.xml b/core/repository/sail/pom.xml
index ed8bced2627..fa88c985bb8 100644
--- a/core/repository/sail/pom.xml
+++ b/core/repository/sail/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-repository
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository-sail
RDF4J: SailRepository
diff --git a/core/repository/sparql/pom.xml b/core/repository/sparql/pom.xml
index ce7bc9cfd4a..6e259f6c8b9 100644
--- a/core/repository/sparql/pom.xml
+++ b/core/repository/sparql/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-repository
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-repository-sparql
RDF4J: SPARQL Repository
diff --git a/core/repository/sparql/src/main/java/org/eclipse/rdf4j/repository/sparql/SPARQLConnection.java b/core/repository/sparql/src/main/java/org/eclipse/rdf4j/repository/sparql/SPARQLConnection.java
index a7073f0eef0..7a2d40346d1 100644
--- a/core/repository/sparql/src/main/java/org/eclipse/rdf4j/repository/sparql/SPARQLConnection.java
+++ b/core/repository/sparql/src/main/java/org/eclipse/rdf4j/repository/sparql/SPARQLConnection.java
@@ -17,7 +17,9 @@
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
+import java.util.Arrays;
import java.util.Objects;
+import java.util.stream.Collectors;
import org.apache.http.client.HttpClient;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
@@ -39,6 +41,8 @@
import org.eclipse.rdf4j.model.impl.DynamicModelFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.util.Literals;
+import org.eclipse.rdf4j.model.vocabulary.RDF4J;
+import org.eclipse.rdf4j.model.vocabulary.SESAME;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.BooleanQuery;
import org.eclipse.rdf4j.query.GraphQuery;
@@ -79,6 +83,8 @@
*/
public class SPARQLConnection extends AbstractRepositoryConnection implements HttpClientDependent {
+ private static final String COUNT_EVERYTHING = "SELECT (COUNT(*) AS ?count) WHERE { ?s ?p ?o }";
+
private static final String EVERYTHING = "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }";
private static final String EVERYTHING_WITH_GRAPH = "SELECT * WHERE { ?s ?p ?o . OPTIONAL { GRAPH ?ctx { ?s ?p ?o } } }";
@@ -281,16 +287,61 @@ public boolean isEmpty() throws RepositoryException {
@Override
public long size(Resource... contexts) throws RepositoryException {
- try (RepositoryResult stmts = getStatements(null, null, null, true, contexts)) {
- long i = 0;
- while (stmts.hasNext()) {
- stmts.next();
- i++;
+ String query = sizeAsTupleQuery(contexts);
+ TupleQuery tq = prepareTupleQuery(SPARQL, query);
+ try (TupleQueryResult res = tq.evaluate()) {
+ if (res.hasNext()) {
+
+ Value value = res.next().getBinding("count").getValue();
+ if (value instanceof Literal) {
+ return ((Literal) value).longValue();
+ } else {
+ return 0;
+ }
+ }
+ } catch (QueryEvaluationException e) {
+ throw new RepositoryException(e);
+ }
+ return 0;
+ }
+
+ String sizeAsTupleQuery(Resource... contexts) {
+
+ // in case the context is null we want the
+ // default graph of the remote store i.e. ask without graph/from.
+ if (contexts != null && isQuadMode() && contexts.length > 0) {
+ // this is an optimization for the case that we can use a GRAPH instead of a FROM.
+ if (contexts.length == 1 && isExposableGraphIri(contexts[0])) {
+ return "SELECT (COUNT(*) AS ?count) WHERE { GRAPH <" + contexts[0].stringValue()
+ + "> { ?s ?p ?o}}";
+ } else {
+ // If we had an default graph setting that is sesame/rdf4j specific
+ // we must drop it before sending it over the wire. Otherwise
+ // gather up the given contexts and send them as a from clauses
+ // to make the matching dataset.
+ String graphs = Arrays.stream(contexts)
+ .filter(SPARQLConnection::isExposableGraphIri)
+ .map(Resource::stringValue)
+ .map(s -> "FROM <" + s + ">")
+ .collect(Collectors.joining(" "));
+ return "SELECT (COUNT(*) AS ?count) " + graphs + "WHERE { ?s ?p ?o}";
}
- return i;
+ } else {
+ return COUNT_EVERYTHING;
}
}
+ /**
+ * For the sparql protocol a context must be an IRI However we can't send out the RDF4j internal default graph IRIs
+ *
+ * @param resource to test if it can be the IRI for a named graph
+ * @return true if it the input can be a foreign named graph.
+ */
+ private static boolean isExposableGraphIri(Resource resource) {
+ // We use the instanceof test to avoid any issue with a null pointer.
+ return resource instanceof IRI && !RDF4J.NIL.equals(resource) && !SESAME.NIL.equals(resource);
+ }
+
@Override
public RepositoryResult getStatements(Resource subj, IRI pred, Value obj, boolean includeInferred,
Resource... contexts) throws RepositoryException {
diff --git a/core/repository/sparql/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLConnectionTest.java b/core/repository/sparql/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLConnectionTest.java
index 081b9d09e07..fb133c58997 100644
--- a/core/repository/sparql/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLConnectionTest.java
+++ b/core/repository/sparql/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLConnectionTest.java
@@ -12,13 +12,20 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.rdf4j.model.util.Values.iri;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.ref.WeakReference;
import org.eclipse.rdf4j.http.client.SPARQLProtocolSession;
import org.eclipse.rdf4j.model.IRI;
@@ -26,11 +33,20 @@
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.vocabulary.FOAF;
import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.RDF4J;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
+import org.eclipse.rdf4j.query.impl.MapBindingSet;
+import org.eclipse.rdf4j.query.impl.SimpleBinding;
+import org.eclipse.rdf4j.query.impl.TupleQueryResultBuilder;
+import org.eclipse.rdf4j.query.parser.ParsedQuery;
+import org.eclipse.rdf4j.query.parser.sparql.SPARQLParser;
+import org.eclipse.rdf4j.query.parser.sparql.SPARQLParserFactory;
import org.eclipse.rdf4j.rio.ParserConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
public class SPARQLConnectionTest {
@@ -100,6 +116,36 @@ public void testAddSingleContextHandling() throws Exception {
assertThat(sparqlUpdate).containsPattern(expectedAddPattern).containsPattern(expectedRemovePattern);
}
+ @Test
+ public void testSizeQuery() throws Exception {
+
+ String sizeAsTupleQuery = subject.sizeAsTupleQuery();
+ ParsedQuery query = new SPARQLParserFactory().getParser().parseQuery(sizeAsTupleQuery, "http://example.org/");
+ assertNotNull(query);
+
+ sizeAsTupleQuery = subject.sizeAsTupleQuery(vf.createIRI("urn:g1"));
+ query = new SPARQLParserFactory().getParser().parseQuery(sizeAsTupleQuery, "http://example.org/");
+ assertNotNull(query);
+
+ sizeAsTupleQuery = subject.sizeAsTupleQuery(vf.createIRI("urn:g1"), vf.createIRI("urn:g2"));
+ query = new SPARQLParserFactory().getParser().parseQuery(sizeAsTupleQuery, "http://example.org/");
+ assertNotNull(query);
+
+ sizeAsTupleQuery = subject.sizeAsTupleQuery(vf.createIRI("urn:g1"), vf.createBNode());
+ query = new SPARQLParserFactory().getParser().parseQuery(sizeAsTupleQuery, "http://example.org/");
+ assertNotNull(query);
+
+ sizeAsTupleQuery = subject.sizeAsTupleQuery(RDF4J.NIL);
+ query = new SPARQLParserFactory().getParser().parseQuery(sizeAsTupleQuery, "http://example.org/");
+ assertNotNull(query);
+ assertFalse(sizeAsTupleQuery.contains("nil"));
+
+ sizeAsTupleQuery = subject.sizeAsTupleQuery(null);
+ query = new SPARQLParserFactory().getParser().parseQuery(sizeAsTupleQuery, "http://example.org/");
+
+ assertNotNull(query);
+ }
+
@Test
public void testAddMultipleContextHandling() throws Exception {
ArgumentCaptor sparqlUpdateCaptor = ArgumentCaptor.forClass(String.class);
diff --git a/core/rio/api/pom.xml b/core/rio/api/pom.xml
index e423ec9b28d..21ffd854962 100644
--- a/core/rio/api/pom.xml
+++ b/core/rio/api/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-api
RDF4J: Rio - API
diff --git a/core/rio/api/src/main/java/org/eclipse/rdf4j/rio/helpers/RDFaParserSettings.java b/core/rio/api/src/main/java/org/eclipse/rdf4j/rio/helpers/RDFaParserSettings.java
index 76d7ead5af1..94ef5ecd731 100644
--- a/core/rio/api/src/main/java/org/eclipse/rdf4j/rio/helpers/RDFaParserSettings.java
+++ b/core/rio/api/src/main/java/org/eclipse/rdf4j/rio/helpers/RDFaParserSettings.java
@@ -35,7 +35,8 @@ public class RDFaParserSettings {
/**
* Enables or disables vocabulary
- * expansion feature.
+ * expansion feature. Note that although these settings are not used within RDF4J, they are in use by external
+ * plugins.
*
* Defaults to false
*
@@ -43,7 +44,6 @@ public class RDFaParserSettings {
*
* @see RDFa Vocabulary Expansion
*/
- @Deprecated(since = "4.3.0", forRemoval = true)
public static final BooleanRioSetting VOCAB_EXPANSION_ENABLED = new BooleanRioSetting(
"org.eclipse.rdf4j.rio.rdfa.vocab_expansion", "Vocabulary Expansion", Boolean.FALSE);
diff --git a/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/AbstractParserHandlingTest.java b/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/AbstractParserHandlingTest.java
index c8225888b62..2623b94c14d 100644
--- a/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/AbstractParserHandlingTest.java
+++ b/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/AbstractParserHandlingTest.java
@@ -11,6 +11,7 @@
package org.eclipse.rdf4j.rio;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -19,10 +20,12 @@
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
+import java.util.Map;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
@@ -115,7 +118,7 @@ public abstract class AbstractParserHandlingTest {
private ParseErrorCollector testListener;
- private Model testStatements;
+ private TestStatementCollector testStatements;
/**
* Returns an {@link InputStream} containing the given RDF statements in a format that is recognised by the
@@ -211,6 +214,7 @@ protected RDFWriter createWriter(OutputStream output) {
}
/**
+ *
*/
@BeforeEach
public void setUp() {
@@ -218,13 +222,82 @@ public void setUp() {
testParser.setValueFactory(vf);
testListener = new ParseErrorCollector();
- testStatements = new LinkedHashModel();
+ testStatements = new TestStatementCollector(new LinkedHashModel());
testParser.setParseErrorListener(testListener);
- testParser.setRDFHandler(new StatementCollector(testStatements));
+ testParser.setRDFHandler(testStatements);
+ }
+
+ private class TestStatementCollector extends StatementCollector {
+
+ private boolean start;
+ private boolean end;
+
+ public TestStatementCollector(Model testStatements) {
+ super(testStatements);
+ }
+
+ @Override
+ public void clear() {
+ super.clear();
+ this.start = false;
+ this.end = false;
+ }
+
+ @Override
+ public void startRDF() throws RDFHandlerException {
+ assertFalse(start, "startRDF was called twice");
+ assertFalse(end, "startRDF was called after endRDF");
+ this.start = true;
+ super.startRDF();
+ }
+
+ @Override
+ public void endRDF() throws RDFHandlerException {
+ assertTrue(start, "startRDF was not called before endRDF");
+ assertFalse(end, "endRDF was called twice");
+ this.end = true;
+ super.endRDF();
+ }
+
+ @Override
+ public void handleComment(String comment) throws RDFHandlerException {
+ assertTrue(start, "startRDF was not called before handleComment");
+ assertFalse(end, "endRDF was called before handleComment");
+ super.handleComment(comment);
+ }
+
+ @Override
+ public void handleStatement(Statement st) {
+ assertTrue(start, "startRDF was not called before handleStatement");
+ assertFalse(end, "endRDF was called before handleStatement");
+ super.handleStatement(st);
+ }
+
+ @Override
+ public void handleNamespace(String prefix, String uri) throws RDFHandlerException {
+ assertTrue(start, "startRDF was not called before handleNamespace");
+ assertFalse(end, "endRDF was called before handleNamespace");
+ super.handleNamespace(prefix, uri);
+ }
+
+ @Override
+ public Collection getStatements() {
+ assertTrue(start, "startRDF was not called before getStatements");
+ assertTrue(end, "endRDF was not called before getStatements");
+ return super.getStatements();
+ }
+
+ @Override
+ public Map getNamespaces() {
+ assertTrue(start, "startRDF was not called before getStatements");
+ assertTrue(end, "endRDF was not called before getStatements");
+ return super.getNamespaces();
+ }
}
/**
+ *
*/
@AfterEach
public void tearDown() {
@@ -390,6 +463,9 @@ public void testUnknownDatatypeWithMessageWithFailCase1() throws Exception {
}
assertErrorListener(0, 1, 0);
+ // Since the parser failed it would not have called endRdf(), so we just overwrite the end variable so that
+ // assertModel(...) doesn't fail
+ testStatements.end = true;
assertModel(new LinkedHashModel());
}
@@ -699,6 +775,9 @@ public void testUnknownLanguageWithMessageWithFailCase1() throws Exception {
}
assertErrorListener(0, 1, 0);
+ // Since the parser failed it would not have called endRdf(), so we just overwrite the end variable so that
+ // assertModel(...) doesn't fail
+ testStatements.end = true;
assertModel(new LinkedHashModel());
}
@@ -917,12 +996,13 @@ public void testSkolemization() throws Exception {
assertErrorListener(0, 0, 0);
// assertModel(expectedModel); // GH-2768 isomorphism is not maintained after skolemization
- assertNotEquals(new HashSet<>(expectedModel), new HashSet<>(testStatements)); // blank nodes not preserved
- assertTrue(Models.subjectBNodes(testStatements).isEmpty()); // skolemized
+ assertNotEquals(new HashSet<>(expectedModel), new HashSet<>(testStatements.getStatements())); // blank nodes not
+ // preserved
+ assertTrue(Models.subjectBNodes(testStatements.getStatements()).isEmpty()); // skolemized
}
@Test
- public void testRDFStarCompatibility() throws Exception {
+ public void testRDFStarCompatibility1() throws Exception {
Model expectedModel = new LinkedHashModel();
Triple t1 = vf.createTriple(vf.createIRI("http://example.com/1"), vf.createIRI("http://example.com/2"),
vf.createLiteral("example", vf.createIRI("http://example.com/3")));
@@ -939,9 +1019,20 @@ public void testRDFStarCompatibility() throws Exception {
testParser.parse(input1, BASE_URI);
assertErrorListener(0, 0, 0);
assertModel(expectedModel);
+ }
- testListener.reset();
- testStatements.clear();
+ @Test
+ public void testRDFStarCompatibility2() throws Exception {
+ Model expectedModel = new LinkedHashModel();
+ Triple t1 = vf.createTriple(vf.createIRI("http://example.com/1"), vf.createIRI("http://example.com/2"),
+ vf.createLiteral("example", vf.createIRI("http://example.com/3")));
+ expectedModel.add(vf.createStatement(t1, DC.SOURCE, vf.createIRI("http://example.com/4")));
+ Triple t2 = vf.createTriple(t1, DC.DATE, vf.createLiteral(new Date()));
+ expectedModel.add(vf.createStatement(vf.createIRI("http://example.com/5"), DC.RELATION, t2));
+ Triple t3 = vf.createTriple(vf.createTriple(vf.createTriple(vf.createIRI("urn:a"), RDF.TYPE,
+ vf.createIRI("urn:b")), vf.createIRI("urn:c"), vf.createIRI("urn:d")), vf.createIRI("urn:e"),
+ vf.createIRI("urn:f"));
+ expectedModel.add(vf.createStatement(t3, vf.createIRI("urn:same"), t3));
// Turn off compatibility on parsing: formats with RDF-star support will produce RDF-star triples,
// non-RDF-star formats will produce IRIs of the kind urn:rdf4j:triple:xxx
@@ -952,22 +1043,26 @@ public void testRDFStarCompatibility() throws Exception {
if (testParser.getRDFFormat().supportsRDFStar()) {
assertModel(expectedModel);
} else {
- assertTrue(testStatements.contains(RDFStarUtil.toRDFEncodedValue(t1), DC.SOURCE,
- vf.createIRI("http://example.com/4")));
- assertTrue(testStatements.contains(vf.createIRI("http://example.com/5"), DC.RELATION,
- RDFStarUtil.toRDFEncodedValue(t2)));
- assertTrue(testStatements.contains(RDFStarUtil.toRDFEncodedValue(t3), vf.createIRI("urn:same"),
- RDFStarUtil.toRDFEncodedValue(t3)));
- assertEquals(3, testStatements.size());
+ assertTrue(testStatements.getStatements()
+ .contains(vf.createStatement(RDFStarUtil.toRDFEncodedValue(t1), DC.SOURCE,
+ vf.createIRI("http://example.com/4"))));
+ assertTrue(testStatements.getStatements()
+ .contains(vf.createStatement(vf.createIRI("http://example.com/5"), DC.RELATION,
+ RDFStarUtil.toRDFEncodedValue(t2))));
+ assertTrue(testStatements.getStatements()
+ .contains(vf.createStatement(RDFStarUtil.toRDFEncodedValue(t3), vf.createIRI("urn:same"),
+ RDFStarUtil.toRDFEncodedValue(t3))));
+ assertEquals(3, testStatements.getStatements().size());
}
}
private void assertModel(Model expectedModel) {
if (logger.isTraceEnabled()) {
logger.trace("Expected: {}", expectedModel);
- logger.trace("Actual: {}", testStatements);
+ logger.trace("Actual: {}", testStatements.getStatements());
}
- assertTrue(Models.isomorphic(expectedModel, testStatements), "Did not find expected statements");
+ assertTrue(Models.isomorphic(expectedModel, testStatements.getStatements()),
+ "Did not find expected statements");
}
private void assertErrorListener(int expectedWarnings, int expectedErrors, int expectedFatalErrors) {
diff --git a/core/rio/binary/pom.xml b/core/rio/binary/pom.xml
index 4659decd397..e59d2265ff9 100644
--- a/core/rio/binary/pom.xml
+++ b/core/rio/binary/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-binary
RDF4J: Rio - Binary
diff --git a/core/rio/datatypes/pom.xml b/core/rio/datatypes/pom.xml
index af965f085d5..4b8d0d984f7 100644
--- a/core/rio/datatypes/pom.xml
+++ b/core/rio/datatypes/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-datatypes
RDF4J: Rio - Datatypes
diff --git a/core/rio/hdt/pom.xml b/core/rio/hdt/pom.xml
index 0c8001d1ac9..c8311ec8f3d 100644
--- a/core/rio/hdt/pom.xml
+++ b/core/rio/hdt/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-hdt
jar
diff --git a/core/rio/jsonld-legacy/pom.xml b/core/rio/jsonld-legacy/pom.xml
index c2bb2b27869..f9574448da9 100644
--- a/core/rio/jsonld-legacy/pom.xml
+++ b/core/rio/jsonld-legacy/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-jsonld-legacy
RDF4J: Rio - JSON-LD 1.0 (legacy)
diff --git a/core/rio/jsonld/pom.xml b/core/rio/jsonld/pom.xml
index 7f4d5404637..ba1528865a2 100644
--- a/core/rio/jsonld/pom.xml
+++ b/core/rio/jsonld/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-jsonld
RDF4J: Rio - JSON-LD
diff --git a/core/rio/jsonld/src/main/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParser.java b/core/rio/jsonld/src/main/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParser.java
index ab8eb983575..69c09c92906 100644
--- a/core/rio/jsonld/src/main/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParser.java
+++ b/core/rio/jsonld/src/main/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParser.java
@@ -20,8 +20,6 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
@@ -44,9 +42,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import jakarta.json.JsonStructure;
@@ -125,6 +120,10 @@ private void parse(InputStream in, Reader reader, String baseURI)
throws RDFParseException, RDFHandlerException, IOException {
clear();
+ if (rdfHandler != null) {
+ rdfHandler.startRDF();
+ }
+
try {
Document document = getDocument(in, reader);
@@ -179,6 +178,9 @@ private void parse(InputStream in, Reader reader, String baseURI)
}
RDFHandler rdfHandler = getRDFHandler();
+ if (rdfHandler != null) {
+ extractPrefixes(document, rdfHandler::handleNamespace);
+ }
JsonLd.toRdf(document).options(opts).base(baseURI).get(new RdfConsumer<>() {
@Override
@@ -242,7 +244,7 @@ public Literal createLangString(String value, String lang) {
});
if (rdfHandler != null) {
- extractPrefixes(document, rdfHandler::handleNamespace);
+ rdfHandler.endRDF();
}
} catch (no.hasmac.jsonld.JsonLdError e) {
diff --git a/core/rio/languages/pom.xml b/core/rio/languages/pom.xml
index 4df04834575..6d671957f1f 100644
--- a/core/rio/languages/pom.xml
+++ b/core/rio/languages/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-languages
RDF4J: Rio - Languages
diff --git a/core/rio/n3/pom.xml b/core/rio/n3/pom.xml
index edfe5961d95..88783b054aa 100644
--- a/core/rio/n3/pom.xml
+++ b/core/rio/n3/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-n3
RDF4J: Rio - N3 (writer-only)
diff --git a/core/rio/nquads/pom.xml b/core/rio/nquads/pom.xml
index a71891a6df4..e0319824e58 100644
--- a/core/rio/nquads/pom.xml
+++ b/core/rio/nquads/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-nquads
RDF4J: Rio - N-Quads
diff --git a/core/rio/ntriples/pom.xml b/core/rio/ntriples/pom.xml
index d546b62f838..dfb56bd96ba 100644
--- a/core/rio/ntriples/pom.xml
+++ b/core/rio/ntriples/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-ntriples
RDF4J: Rio - N-Triples
diff --git a/core/rio/pom.xml b/core/rio/pom.xml
index 433fd04b0fb..d7f3720f3cc 100644
--- a/core/rio/pom.xml
+++ b/core/rio/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-core
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio
pom
diff --git a/core/rio/rdfjson/pom.xml b/core/rio/rdfjson/pom.xml
index 5b783ee1eb9..f9dc87e07e5 100644
--- a/core/rio/rdfjson/pom.xml
+++ b/core/rio/rdfjson/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-rdfjson
RDF4J: Rio - RDF/JSON
diff --git a/core/rio/rdfxml/pom.xml b/core/rio/rdfxml/pom.xml
index a6ae84c0e09..b035b9b2499 100644
--- a/core/rio/rdfxml/pom.xml
+++ b/core/rio/rdfxml/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-rdfxml
RDF4J: Rio - RDF/XML
diff --git a/core/rio/trig/pom.xml b/core/rio/trig/pom.xml
index feaa83bed41..cdff54ce2dd 100644
--- a/core/rio/trig/pom.xml
+++ b/core/rio/trig/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-trig
RDF4J: Rio - TriG
diff --git a/core/rio/trix/pom.xml b/core/rio/trix/pom.xml
index 424c3d323be..8ddf9023a38 100644
--- a/core/rio/trix/pom.xml
+++ b/core/rio/trix/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-trix
RDF4J: Rio - TriX
diff --git a/core/rio/turtle/pom.xml b/core/rio/turtle/pom.xml
index 2ce7fd5b7ae..1d6259265fb 100644
--- a/core/rio/turtle/pom.xml
+++ b/core/rio/turtle/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-rio
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-rio-turtle
RDF4J: Rio - Turtle
diff --git a/core/sail/api/pom.xml b/core/sail/api/pom.xml
index 3dea2c7c5bc..b454546a40d 100644
--- a/core/sail/api/pom.xml
+++ b/core/sail/api/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-api
RDF4J: Sail API
diff --git a/core/sail/api/src/main/java/org/eclipse/rdf4j/common/concurrent/locks/ExclusiveReentrantLockManager.java b/core/sail/api/src/main/java/org/eclipse/rdf4j/common/concurrent/locks/ExclusiveReentrantLockManager.java
new file mode 100644
index 00000000000..6ac7fa4df12
--- /dev/null
+++ b/core/sail/api/src/main/java/org/eclipse/rdf4j/common/concurrent/locks/ExclusiveReentrantLockManager.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Eclipse RDF4J contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Distribution License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.rdf4j.common.concurrent.locks;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.rdf4j.common.concurrent.locks.diagnostics.LockCleaner;
+import org.eclipse.rdf4j.common.concurrent.locks.diagnostics.LockMonitoring;
+import org.eclipse.rdf4j.common.concurrent.locks.diagnostics.LockTracking;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A simple reentrant lock that allows other threads to unlock the lock.
+ *
+ * @author Håvard M. Ottestad
+ */
+public class ExclusiveReentrantLockManager {
+
+ private final static Logger logger = LoggerFactory.getLogger(ExclusiveReentrantLockManager.class);
+
+ // the underlying lock object
+ final AtomicLong activeLocks = new AtomicLong();
+ final AtomicReference owner = new AtomicReference<>();
+
+ private final int waitToCollect;
+
+ LockMonitoring lockMonitoring;
+
+ public ExclusiveReentrantLockManager() {
+ this(false);
+ }
+
+ public ExclusiveReentrantLockManager(boolean trackLocks) {
+ this(trackLocks, LockMonitoring.INITIAL_WAIT_TO_COLLECT);
+ }
+
+ public ExclusiveReentrantLockManager(boolean trackLocks, int collectionFrequency) {
+
+ this.waitToCollect = collectionFrequency;
+
+ if (trackLocks || Properties.lockTrackingEnabled()) {
+
+ lockMonitoring = new LockTracking(
+ true,
+ "ExclusiveReentrantLockManager",
+ LoggerFactory.getLogger(this.getClass()),
+ waitToCollect,
+ Lock.ExtendedSupplier.wrap(this::getExclusiveLockInner, this::tryExclusiveLockInner)
+ );
+
+ } else {
+ lockMonitoring = new LockCleaner(
+ false,
+ "ExclusiveReentrantLockManager",
+ LoggerFactory.getLogger(this.getClass()),
+ Lock.ExtendedSupplier.wrap(this::getExclusiveLockInner, this::tryExclusiveLockInner)
+ );
+ }
+
+ }
+
+ private Lock tryExclusiveLockInner() {
+
+ synchronized (owner) {
+ if (owner.get() == Thread.currentThread()) {
+ activeLocks.incrementAndGet();
+ return new ExclusiveReentrantLock(owner, activeLocks);
+ }
+
+ if (owner.compareAndSet(null, Thread.currentThread())) {
+ activeLocks.incrementAndGet();
+ return new ExclusiveReentrantLock(owner, activeLocks);
+ }
+ }
+
+ return null;
+
+ }
+
+ private Lock getExclusiveLockInner() throws InterruptedException {
+
+ synchronized (owner) {
+
+ if (lockMonitoring.requiresManualCleanup()) {
+ do {
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
+ Lock lock = tryExclusiveLockInner();
+ if (lock != null) {
+ return lock;
+ } else {
+ lockMonitoring.runCleanup();
+ owner.wait(waitToCollect);
+ }
+ } while (true);
+ } else {
+ while (true) {
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
+ Lock lock = tryExclusiveLockInner();
+ if (lock != null) {
+ return lock;
+ } else {
+ owner.wait(waitToCollect);
+ }
+ }
+ }
+ }
+ }
+
+ public Lock tryExclusiveLock() {
+ return lockMonitoring.tryLock();
+ }
+
+ public Lock getExclusiveLock() throws InterruptedException {
+ return lockMonitoring.getLock();
+ }
+
+ public boolean isActiveLock() {
+ return owner.get() != null;
+ }
+
+ static class ExclusiveReentrantLock implements Lock {
+
+ final AtomicLong activeLocks;
+ final AtomicReference owner;
+ private boolean released = false;
+
+ public ExclusiveReentrantLock(AtomicReference owner, AtomicLong activeLocks) {
+ this.owner = owner;
+ this.activeLocks = activeLocks;
+ }
+
+ @Override
+ public boolean isActive() {
+ return !released;
+ }
+
+ @Override
+ public void release() {
+ if (released) {
+ throw new IllegalStateException("Lock already released");
+ }
+
+ synchronized (owner) {
+ if (owner.get() != Thread.currentThread()) {
+ logger.warn("Releasing lock from different thread, owner: " + owner.get() + ", current: "
+ + Thread.currentThread());
+ }
+
+ if (activeLocks.decrementAndGet() == 0) {
+ owner.set(null);
+ owner.notifyAll();
+ }
+ }
+
+ released = true;
+
+ }
+ }
+
+}
diff --git a/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnection.java b/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnection.java
index 589d3d8a8ef..ca9bb7b60fb 100644
--- a/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnection.java
+++ b/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnection.java
@@ -19,6 +19,7 @@
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
@@ -94,6 +95,7 @@ public abstract class AbstractSailConnection implements SailConnection {
*/
private final LongAdder blockClose = new LongAdder();
private final LongAdder unblockClose = new LongAdder();
+ private final AtomicReference activeThread = new AtomicReference<>();
@SuppressWarnings("FieldMayBeFinal")
private boolean isOpen = true;
@@ -107,7 +109,6 @@ public abstract class AbstractSailConnection implements SailConnection {
*
*/
private final ReentrantLock updateLock = new ReentrantLock();
-
private final LongAdder iterationsOpened = new LongAdder();
private final LongAdder iterationsClosed = new LongAdder();
@@ -196,6 +197,8 @@ public void begin(IsolationLevel isolationLevel) throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
updateLock.lock();
@@ -210,7 +213,12 @@ public void begin(IsolationLevel isolationLevel) throws SailException {
updateLock.unlock();
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
+
}
startUpdate(null);
}
@@ -231,7 +239,6 @@ public boolean isActive() throws UnknownSailTransactionStateException {
@Override
public final void close() throws SailException {
- Thread deadlockPreventionThread = startDeadlockPreventionThread();
// obtain an exclusive lock so that any further operations on this
// connection (including those from any concurrent threads) are blocked.
@@ -240,96 +247,75 @@ public final void close() throws SailException {
}
try {
- while (true) {
- long sumDone = unblockClose.sum();
- long sumBlocking = blockClose.sum();
- if (sumDone == sumBlocking) {
- break;
- } else {
- if (Thread.currentThread().isInterrupted()) {
- throw new SailException(
- "Connection was interrupted while waiting on active operations before it could be closed.");
- } else {
- LockSupport.parkNanos(Duration.ofMillis(10).toNanos());
- }
- }
- }
+ waitForOtherOperations(true);
try {
- forceCloseActiveOperations();
-
- if (txnActive) {
- logger.warn("Rolling back transaction due to connection close",
- debugEnabled ? new Throwable() : null);
- try {
- // Use internal method to avoid deadlock: the public
- // rollback method will try to obtain a connection lock
- rollbackInternal();
- } finally {
- txnActive = false;
- txnPrepared = false;
+ try {
+ forceCloseActiveOperations();
+ } finally {
+ if (txnActive) {
+ logger.warn("Rolling back transaction due to connection close",
+ debugEnabled ? new Throwable() : null);
+ try {
+ // Use internal method to avoid deadlock: the public
+ // rollback method will try to obtain a connection lock
+ rollbackInternal();
+ } finally {
+ txnActive = false;
+ txnPrepared = false;
+ }
}
- }
- closeInternal();
+ closeInternal();
- if (isActiveOperation()) {
- throw new SailException("Connection closed before all iterations were closed.");
+ if (isActiveOperation()) {
+ throw new SailException("Connection closed before all iterations were closed.");
+ }
}
+
} finally {
sailBase.connectionClosed(this);
}
} finally {
- if (deadlockPreventionThread != null) {
- deadlockPreventionThread.interrupt();
- }
}
}
- /**
- * If the current thread is not the owner, starts a thread to handle potential deadlocks by interrupting the owner.
- *
- * @return The started deadlock prevention thread or null if the current thread is the owner.
- */
- private Thread startDeadlockPreventionThread() {
- Thread deadlockPreventionThread = null;
-
- if (Thread.currentThread() != owner) {
-
- if (logger.isInfoEnabled()) {
- // use info level for this because FedX prevalently closes connections from different threads
- logger.info(
- "Closing connection from a different thread than the one that opened it. Connections should not be shared between threads. Opened by {} closed by {}",
- owner, Thread.currentThread(), new Throwable("Throwable used for stacktrace"));
- }
-
- deadlockPreventionThread = new Thread(() -> {
- try {
- // This thread should sleep for a while so that the callee has a chance to finish.
- // The callee will interrupt this thread when it is finished, which means that there were no
- // deadlocks and we can exit.
- Thread.sleep(sailBase.connectionTimeOut / 2);
-
- owner.interrupt();
- // wait for up to 1 second for the owner thread to die
- owner.join(1000);
- if (owner.isAlive()) {
- logger.error("Interrupted thread {} but thread is still alive after 1000 ms!", owner);
+ @InternalUseOnly
+ public void waitForOtherOperations(boolean interrupt) {
+ int i = 0;
+ boolean interrupted = false;
+ while (true) {
+ long sumDone = unblockClose.sum();
+ long sumBlocking = blockClose.sum();
+ if (sumDone == sumBlocking) {
+ if (interrupted) {
+ logger.warn(
+ "Connection is no longer blocked by concurrent operation after interrupting the active thread");
+ }
+ break;
+ } else {
+ if (Thread.currentThread().isInterrupted()) {
+ throw new SailException(
+ "Connection was interrupted while waiting on concurrent operations before it could be closed.");
+ } else {
+ LockSupport.parkNanos(Duration.ofMillis(10).toNanos());
+ if (++i % 500 == 0) { // wait for 5 seconds before logging and interrupting
+ Thread acquire = activeThread.getAcquire();
+ if (acquire != null) {
+ logger.warn("Connection is blocked by concurrent operation in thread: {}", acquire);
+ if (interrupt) {
+ acquire.interrupt();
+ interrupted = true;
+ logger.error(
+ "Connection is blocked by concurrent operation in thread {} which was interrupted to attempt to forcefully abort the concurrent operation.",
+ acquire);
+ }
+ }
}
-
- } catch (InterruptedException ignored) {
- // this thread is interrupted as a signal that there were no deadlocks, so the exception can be
- // ignored and we can simply exit
}
-
- });
-
- deadlockPreventionThread.setDaemon(true);
- deadlockPreventionThread.start();
-
+ }
}
- return deadlockPreventionThread;
}
@Override
@@ -339,6 +325,8 @@ public final CloseableIteration extends BindingSet> evaluate(TupleExpr tupleEx
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
CloseableIteration extends BindingSet> iteration = null;
try {
@@ -354,7 +342,11 @@ public final CloseableIteration extends BindingSet> evaluate(TupleExpr tupleEx
throw t;
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -364,10 +356,16 @@ public final CloseableIteration extends Resource> getContextIDs() throws SailE
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
return registerIteration(getContextIDsInternal());
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -378,6 +376,7 @@ public final CloseableIteration extends Statement> getStatements(Resource subj
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
verifyIsOpen();
CloseableIteration extends Statement> iteration = null;
try {
@@ -390,7 +389,11 @@ public final CloseableIteration extends Statement> getStatements(Resource subj
throw t;
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -424,10 +427,15 @@ public final boolean hasStatement(Resource subj, IRI pred, Value obj, boolean in
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
verifyIsOpen();
return hasStatementInternal(subj, pred, obj, includeInferred, contexts);
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -445,10 +453,15 @@ public final long size(Resource... contexts) throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
verifyIsOpen();
return sizeInternal(contexts);
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -489,6 +502,7 @@ public final void prepare() throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
verifyIsOpen();
updateLock.lock();
@@ -501,7 +515,11 @@ public final void prepare() throws SailException {
updateLock.unlock();
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -513,6 +531,8 @@ public final void commit() throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
updateLock.lock();
@@ -529,7 +549,11 @@ public final void commit() throws SailException {
updateLock.unlock();
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -544,6 +568,8 @@ public final void rollback() throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
updateLock.lock();
@@ -563,7 +589,11 @@ public final void rollback() throws SailException {
updateLock.unlock();
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -660,6 +690,8 @@ public final void endUpdate(UpdateContext op) throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
updateLock.lock();
@@ -670,8 +702,11 @@ public final void endUpdate(UpdateContext op) throws SailException {
updateLock.unlock();
}
} finally {
- unblockClose.increment();
-
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
if (op != null) {
flush();
}
@@ -711,6 +746,8 @@ public final void clear(Resource... contexts) throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
updateLock.lock();
@@ -722,19 +759,27 @@ public final void clear(Resource... contexts) throws SailException {
updateLock.unlock();
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@Override
public final CloseableIteration extends Namespace> getNamespaces() throws SailException {
-
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
verifyIsOpen();
return registerIteration(getNamespacesInternal());
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -745,11 +790,18 @@ public final String getNamespace(String prefix) throws SailException {
}
blockClose.increment();
+
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
return getNamespaceInternal(prefix);
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -764,6 +816,8 @@ public final void setNamespace(String prefix, String name) throws SailException
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
updateLock.lock();
@@ -774,7 +828,11 @@ public final void setNamespace(String prefix, String name) throws SailException
updateLock.unlock();
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -786,6 +844,8 @@ public final void removeNamespace(String prefix) throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
updateLock.lock();
@@ -796,7 +856,11 @@ public final void removeNamespace(String prefix) throws SailException {
updateLock.unlock();
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -805,6 +869,8 @@ public final void clearNamespaces() throws SailException {
blockClose.increment();
try {
+ activeThread.setRelease(Thread.currentThread());
+
verifyIsOpen();
updateLock.lock();
@@ -815,7 +881,11 @@ public final void clearNamespaces() throws SailException {
updateLock.unlock();
}
} finally {
- unblockClose.increment();
+ try {
+ activeThread.setRelease(null);
+ } finally {
+ unblockClose.increment();
+ }
}
}
@@ -930,47 +1000,40 @@ protected AbstractSail getSailBase() {
}
private void forceCloseActiveOperations() throws SailException {
- Thread deadlockPreventionThread = startDeadlockPreventionThread();
- try {
- for (int i = 0; i < 10 && isActiveOperation() && !debugEnabled; i++) {
- System.gc();
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new SailException(e);
- }
+ for (int i = 0; i < 10 && isActiveOperation() && !debugEnabled; i++) {
+ System.gc();
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new SailException(e);
}
+ }
- if (debugEnabled) {
+ if (debugEnabled) {
- var activeIterationsCopy = new IdentityHashMap<>(activeIterationsDebug);
- activeIterationsDebug.clear();
+ var activeIterationsCopy = new IdentityHashMap<>(activeIterationsDebug);
+ activeIterationsDebug.clear();
- if (!activeIterationsCopy.isEmpty()) {
- for (var entry : activeIterationsCopy.entrySet()) {
- try {
- logger.warn("Unclosed iteration", entry.getValue());
- entry.getKey().close();
- } catch (Exception e) {
- if (e instanceof InterruptedException) {
- Thread.currentThread().interrupt();
- throw new SailException(e);
- }
- logger.warn("Exception occurred while closing unclosed iterations.", e);
+ if (!activeIterationsCopy.isEmpty()) {
+ for (var entry : activeIterationsCopy.entrySet()) {
+ try {
+ logger.warn("Unclosed iteration", entry.getValue());
+ entry.getKey().close();
+ } catch (Exception e) {
+ if (e instanceof InterruptedException) {
+ Thread.currentThread().interrupt();
+ throw new SailException(e);
}
+ logger.warn("Exception occurred while closing unclosed iterations.", e);
}
+ }
- var entry = activeIterationsCopy.entrySet().stream().findAny().orElseThrow();
+ var entry = activeIterationsCopy.entrySet().stream().findAny().orElseThrow();
- throw new SailException(
- "Connection closed before all iterations were closed: " + entry.getKey().toString(),
- entry.getValue());
- }
- }
- } finally {
- if (deadlockPreventionThread != null) {
- deadlockPreventionThread.interrupt();
+ throw new SailException(
+ "Connection closed before all iterations were closed: " + entry.getKey().toString(),
+ entry.getValue());
}
}
diff --git a/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/ExclusiveReentrantLockManagerTest.java b/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/ExclusiveReentrantLockManagerTest.java
new file mode 100644
index 00000000000..83fe59d93ea
--- /dev/null
+++ b/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/ExclusiveReentrantLockManagerTest.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Eclipse RDF4J contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Distribution License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *******************************************************************************/
+package org.eclipse.rdf4j.common.concurrent.locks;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+
+class ExclusiveReentrantLockManagerTest {
+
+ private ExclusiveReentrantLockManager lockManager;
+ private ExclusiveReentrantLockManager lockManagerTracking;
+ private MemoryAppender memoryAppender;
+
+ @BeforeEach
+ void beforeEach() {
+ Properties.setLockTrackingEnabled(false);
+ lockManager = new ExclusiveReentrantLockManager(false, 1);
+ lockManagerTracking = new ExclusiveReentrantLockManager(true, 1);
+
+ Logger logger = (Logger) LoggerFactory.getLogger(ExclusiveReentrantLockManager.class.getName());
+ memoryAppender = new MemoryAppender();
+ memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory());
+ logger.detachAndStopAllAppenders();
+ logger.setLevel(Level.INFO);
+ logger.addAppender(memoryAppender);
+ memoryAppender.start();
+
+ }
+
+ @Test
+ void createLock() throws InterruptedException {
+ Lock lock = lockManager.getExclusiveLock();
+ assertTrue(lock.isActive());
+ lock.release();
+ assertFalse(lock.isActive());
+ }
+
+ @Test
+ @Timeout(2)
+ void cleanupUnreleasedLocks() throws InterruptedException {
+
+ lock(lockManager);
+
+ TestHelper.callGC(lockManager);
+
+ Lock exclusiveLock = lockManager.getExclusiveLock();
+ exclusiveLock.release();
+
+ }
+
+ @Test
+ @Timeout(2)
+ void cleanupUnreleasedLocksWithTracking() throws InterruptedException {
+
+ lock(lockManagerTracking);
+
+ Lock exclusiveLock = lockManagerTracking.getExclusiveLock();
+ exclusiveLock.release();
+
+ memoryAppender.waitForEvents(2);
+
+ assertThat(memoryAppender.countEventsForLogger(ExclusiveReentrantLockManager.class.getName())).isEqualTo(2);
+ memoryAppender.assertContains(
+ "at org.eclipse.rdf4j.common.concurrent.locks.ExclusiveReentrantLockManagerTest.lambda$lock$2",
+ Level.WARN);
+
+ }
+
+ @Test
+ @Timeout(2)
+ void stalledTest() throws InterruptedException {
+
+ AtomicReference exclusiveLock1 = new AtomicReference<>();
+ Thread thread = new Thread(() -> {
+ try {
+ exclusiveLock1.set(lockManagerTracking.getExclusiveLock());
+ } catch (InterruptedException ignored) {
+ }
+ });
+ thread.start();
+ thread.join();
+
+ try {
+ thread = new Thread(() -> {
+ try {
+ Lock exclusiveLock2 = lockManagerTracking.getExclusiveLock();
+ exclusiveLock2.release();
+ } catch (InterruptedException ignored) {
+ }
+ });
+
+ thread.setDaemon(true);
+ thread.start();
+
+ memoryAppender.waitForEvents();
+
+ } finally {
+ TestHelper.interruptAndJoin(thread);
+ }
+
+ assertNull(lockManagerTracking.tryExclusiveLock());
+ assertTrue(exclusiveLock1.get().isActive());
+ exclusiveLock1.get().release();
+ assertFalse(exclusiveLock1.get().isActive());
+
+ memoryAppender.waitForEvents(2);
+
+ assertThat(memoryAppender.countEventsForLogger(ExclusiveReentrantLockManager.class.getName()))
+ .isGreaterThanOrEqualTo(1);
+ memoryAppender.assertContains("is waiting on a possibly stalled lock \"ExclusiveReentrantLockManager\" with id",
+ Level.INFO);
+ memoryAppender.assertContains(
+ "at org.eclipse.rdf4j.common.concurrent.locks.ExclusiveReentrantLockManagerTest.lambda$stalledTest$0(ExclusiveReentrantLockManagerTest.java:",
+ Level.INFO);
+
+ }
+
+ private void lock(ExclusiveReentrantLockManager lockManager) throws InterruptedException {
+ Thread thread = new Thread(() -> {
+ try {
+ lockManager.getExclusiveLock();
+ } catch (InterruptedException ignored) {
+ }
+ });
+ thread.start();
+ thread.join(2000);
+ assertThat(thread.isAlive()).isFalse();
+ }
+}
diff --git a/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/MemoryAppender.java b/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/MemoryAppender.java
index e1fc0fc3b19..1e3d9b9e171 100644
--- a/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/MemoryAppender.java
+++ b/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/MemoryAppender.java
@@ -99,6 +99,18 @@ public String toString() {
public void waitForEvents() {
while (list.isEmpty()) {
try {
+ System.gc();
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ public void waitForEvents(int size) {
+ while (list.size() < size) {
+ try {
+ System.gc();
Thread.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
diff --git a/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/TestHelper.java b/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/TestHelper.java
index cee18c9e1a8..1c57b527465 100644
--- a/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/TestHelper.java
+++ b/core/sail/api/src/test/java/org/eclipse/rdf4j/common/concurrent/locks/TestHelper.java
@@ -42,6 +42,13 @@ public static void callGC(LockManager lockManager) throws InterruptedException {
}
}
+ public static void callGC(ExclusiveReentrantLockManager lockManager) throws InterruptedException {
+ while (lockManager.isActiveLock()) {
+ System.gc();
+ Thread.sleep(1);
+ }
+ }
+
public static void interruptAndJoin(Thread thread) throws InterruptedException {
assertNotNull(thread);
thread.interrupt();
diff --git a/core/sail/base/pom.xml b/core/sail/base/pom.xml
index 12ea493053c..23d9cddb9bf 100644
--- a/core/sail/base/pom.xml
+++ b/core/sail/base/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-base
RDF4J: Sail base implementations
diff --git a/core/sail/elasticsearch-store/pom.xml b/core/sail/elasticsearch-store/pom.xml
index a50f44b1d19..1f3791f76c6 100644
--- a/core/sail/elasticsearch-store/pom.xml
+++ b/core/sail/elasticsearch-store/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-elasticsearch-store
RDF4J: Elasticsearch Store
diff --git a/core/sail/elasticsearch/pom.xml b/core/sail/elasticsearch/pom.xml
index 8e75a6305ac..dc30ae7b5f5 100644
--- a/core/sail/elasticsearch/pom.xml
+++ b/core/sail/elasticsearch/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-elasticsearch
RDF4J: Elastic Search Sail Index
diff --git a/core/sail/extensible-store/pom.xml b/core/sail/extensible-store/pom.xml
index 63ab44b9305..6103dcbbd53 100644
--- a/core/sail/extensible-store/pom.xml
+++ b/core/sail/extensible-store/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-extensible-store
RDF4J: Extensible Store
diff --git a/core/sail/inferencer/pom.xml b/core/sail/inferencer/pom.xml
index 531f0e3a8c3..1f6ad930f5b 100644
--- a/core/sail/inferencer/pom.xml
+++ b/core/sail/inferencer/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-inferencer
RDF4J: Inferencer Sails
diff --git a/core/sail/lmdb/pom.xml b/core/sail/lmdb/pom.xml
index b2027f9b10d..1486dab2eaf 100644
--- a/core/sail/lmdb/pom.xml
+++ b/core/sail/lmdb/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-lmdb
RDF4J: LmdbStore
diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbContextIdIterator.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbContextIdIterator.java
index 5dd7c82a954..1e81df6fd98 100644
--- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbContextIdIterator.java
+++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbContextIdIterator.java
@@ -104,12 +104,12 @@ public long[] next() {
Varint.writeUnsigned(minKeyBuf, record[0]);
minKeyBuf.flip();
keyData.mv_data(minKeyBuf);
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET));
- if (lastResult != 0) {
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_SET);
+ if (lastResult != MDB_SUCCESS) {
// use MDB_SET_RANGE if key was deleted
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
}
- if (lastResult != 0) {
+ if (lastResult != MDB_SUCCESS) {
closeInternal(false);
return null;
}
@@ -119,16 +119,16 @@ public long[] next() {
}
if (fetchNext) {
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT);
fetchNext = false;
} else {
if (minKeyBuf != null) {
// set cursor to min key
keyData.mv_data(minKeyBuf);
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
} else {
// set cursor to first item
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT);
}
}
diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbRecordIterator.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbRecordIterator.java
index 1bcd6938d3c..dbdb69479f7 100644
--- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbRecordIterator.java
+++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbRecordIterator.java
@@ -138,12 +138,12 @@ public long[] next() {
index.toKey(minKeyBuf, quad[0], quad[1], quad[2], quad[3]);
minKeyBuf.flip();
keyData.mv_data(minKeyBuf);
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET));
- if (lastResult != 0) {
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_SET);
+ if (lastResult != MDB_SUCCESS) {
// use MDB_SET_RANGE if key was deleted
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
}
- if (lastResult != 0) {
+ if (lastResult != MDB_SUCCESS) {
closeInternal(false);
return null;
}
@@ -153,16 +153,16 @@ public long[] next() {
}
if (fetchNext) {
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT);
fetchNext = false;
} else {
if (minKeyBuf != null) {
// set cursor to min key
keyData.mv_data(minKeyBuf);
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
} else {
// set cursor to first item
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT);
}
}
@@ -172,7 +172,7 @@ public long[] next() {
lastResult = MDB_NOTFOUND;
} else if (groupMatcher != null && !groupMatcher.matches(keyData.mv_data())) {
// value doesn't match search key/mask, fetch next value
- lastResult = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT));
+ lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT);
} else {
// Matching value found
index.keyToQuad(keyData.mv_data(), quad);
@@ -183,8 +183,6 @@ public long[] next() {
}
closeInternal(false);
return null;
- } catch (IOException e) {
- throw new SailException(e);
} finally {
txnLock.unlockRead(stamp);
}
diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbSailStore.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbSailStore.java
index 76f72f415e2..02e7d71bf5d 100644
--- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbSailStore.java
+++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbSailStore.java
@@ -572,12 +572,14 @@ public void approve(Resource subj, IRI pred, Value obj, Resource ctx) throws Sai
@Override
public void approveAll(Set approved, Set approvedContexts) {
+ Statement last = null;
sinkStoreAccessLock.lock();
try {
startTransaction(true);
for (Statement statement : approved) {
+ last = statement;
Resource subj = statement.getSubject();
IRI pred = statement.getPredicate();
Value obj = statement.getObject();
@@ -604,13 +606,20 @@ public void approveAll(Set approved, Set approvedContexts)
}
}
- } catch (IOException e) {
+ } catch (IOException | RuntimeException e) {
rollback();
+ if (multiThreadingActive) {
+ logger.error("Encountered an unexpected problem while trying to add a statement.", e);
+ } else {
+ logger.error(
+ "Encountered an unexpected problem while trying to add a statement. Last statement that was attempted to be added: [ {} ]",
+ last, e);
+ }
+
+ if (e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ }
throw new SailException(e);
- } catch (RuntimeException e) {
- rollback();
- logger.error("Encountered an unexpected problem while trying to add a statement", e);
- throw e;
} finally {
sinkStoreAccessLock.unlock();
}
diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbUtil.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbUtil.java
index 89e1650686a..9a2c68f7083 100644
--- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbUtil.java
+++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbUtil.java
@@ -16,6 +16,7 @@
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.NULL;
+import static org.lwjgl.util.lmdb.LMDB.MDB_DBS_FULL;
import static org.lwjgl.util.lmdb.LMDB.MDB_KEYEXIST;
import static org.lwjgl.util.lmdb.LMDB.MDB_NOTFOUND;
import static org.lwjgl.util.lmdb.LMDB.MDB_RDONLY;
@@ -39,12 +40,16 @@
import org.lwjgl.system.Pointer;
import org.lwjgl.util.lmdb.MDBCmpFuncI;
import org.lwjgl.util.lmdb.MDBVal;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Utility class for working with LMDB.
*/
final class LmdbUtil {
+ private static final Logger logger = LoggerFactory.getLogger(LmdbUtil.class);
+
/**
* Minimum free space in an LMDB db before automatically resizing the map.
*/
@@ -61,7 +66,9 @@ private LmdbUtil() {
static int E(int rc) throws IOException {
if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND && rc != MDB_KEYEXIST) {
- throw new IOException(mdb_strerror(rc));
+ IOException ioException = new IOException(mdb_strerror(rc));
+ logger.info("Possible LMDB error: {}", mdb_strerror(rc), ioException);
+ throw ioException;
}
return rc;
}
@@ -105,7 +112,7 @@ static T transaction(long env, Transaction transaction) throws IOExceptio
int err;
try {
ret = transaction.exec(stack, txn);
- err = E(mdb_txn_commit(txn));
+ err = mdb_txn_commit(txn);
} catch (Throwable t) {
mdb_txn_abort(txn);
throw t;
diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/PersistentSet.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/PersistentSet.java
index b0bbd20aa38..79d27cf4b7a 100644
--- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/PersistentSet.java
+++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/PersistentSet.java
@@ -12,6 +12,7 @@
import static org.eclipse.rdf4j.sail.lmdb.LmdbUtil.E;
import static org.lwjgl.system.MemoryUtil.NULL;
+import static org.lwjgl.util.lmdb.LMDB.MDB_MAP_FULL;
import static org.lwjgl.util.lmdb.LMDB.MDB_NEXT;
import static org.lwjgl.util.lmdb.LMDB.MDB_NOOVERWRITE;
import static org.lwjgl.util.lmdb.LMDB.MDB_SET;
@@ -24,6 +25,7 @@
import static org.lwjgl.util.lmdb.LMDB.mdb_del;
import static org.lwjgl.util.lmdb.LMDB.mdb_drop;
import static org.lwjgl.util.lmdb.LMDB.mdb_put;
+import static org.lwjgl.util.lmdb.LMDB.mdb_strerror;
import static org.lwjgl.util.lmdb.LMDB.mdb_txn_abort;
import static org.lwjgl.util.lmdb.LMDB.mdb_txn_begin;
@@ -43,12 +45,16 @@
import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.util.lmdb.MDBVal;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A LMDB-based persistent set.
*/
class PersistentSet extends AbstractSet {
+ private static final Logger logger = LoggerFactory.getLogger(PersistentSet.class);
+
private PersistentSetFactory factory;
private final int dbi;
private int size;
@@ -126,15 +132,35 @@ private synchronized boolean update(Object element, boolean add) throws IOExcept
keyVal.mv_data(keyBuf);
if (add) {
- if (E(mdb_put(factory.writeTxn, dbi, keyVal, dataVal, MDB_NOOVERWRITE)) == MDB_SUCCESS) {
+ int rc = mdb_put(factory.writeTxn, dbi, keyVal, dataVal, MDB_NOOVERWRITE);
+ if (rc == MDB_SUCCESS) {
size++;
return true;
+ } else if (rc == MDB_MAP_FULL) {
+ factory.ensureResize();
+ if (mdb_put(factory.writeTxn, dbi, keyVal, dataVal, MDB_NOOVERWRITE) == MDB_SUCCESS) {
+ size++;
+ return true;
+ }
+ return false;
+ } else {
+ logger.debug("Failed to add element due to error {}: {}", mdb_strerror(rc), element);
}
} else {
// delete element
- if (mdb_del(factory.writeTxn, dbi, keyVal, dataVal) == MDB_SUCCESS) {
+ int rc = mdb_del(factory.writeTxn, dbi, keyVal, dataVal);
+ if (rc == MDB_SUCCESS) {
size--;
return true;
+ } else if (rc == MDB_MAP_FULL) {
+ factory.ensureResize();
+ if (mdb_del(factory.writeTxn, dbi, keyVal, dataVal) == MDB_SUCCESS) {
+ size--;
+ return true;
+ }
+ return false;
+ } else {
+ logger.debug("Failed to remove element due to error {}: {}", mdb_strerror(rc), element);
}
}
return false;
diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/TripleStore.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/TripleStore.java
index 7c0c79c7448..d848d30dd5b 100644
--- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/TripleStore.java
+++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/TripleStore.java
@@ -561,7 +561,7 @@ protected void filterUsedIds(Collection ids) throws IOException {
keyBuf.clear();
Varint.writeUnsigned(keyBuf, id);
keyData.mv_data(keyBuf.flip());
- if (E(mdb_get(txn, contextsDbi, keyData, valueData)) == MDB_SUCCESS) {
+ if (mdb_get(txn, contextsDbi, keyData, valueData) == MDB_SUCCESS) {
it.remove();
}
}
@@ -587,7 +587,7 @@ protected void filterUsedIds(Collection ids) throws IOException {
if (fullScan) {
long[] quad = new long[4];
- int rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_FIRST));
+ int rc = mdb_cursor_get(cursor, keyData, valueData, MDB_FIRST);
while (rc == MDB_SUCCESS && !ids.isEmpty()) {
index.keyToQuad(keyData.mv_data(), quad);
ids.remove(quad[0]);
@@ -595,7 +595,7 @@ protected void filterUsedIds(Collection ids) throws IOException {
ids.remove(quad[2]);
ids.remove(quad[3]);
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT));
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT);
}
} else {
for (Iterator it = ids.iterator(); it.hasNext();) {
@@ -625,15 +625,15 @@ protected void filterUsedIds(Collection ids) throws IOException {
// set cursor to min key
keyData.mv_data(keyBuf);
- int rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
+ int rc = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
boolean exists = false;
- while (!exists && rc == 0) {
+ while (!exists && rc == MDB_SUCCESS) {
if (mdb_cmp(txn, dbi, keyData, maxKey) > 0) {
// id was not found
break;
} else if (!matcher.matches(keyData.mv_data())) {
// value doesn't match search key/mask, fetch next value
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT));
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT);
} else {
exists = true;
}
@@ -708,8 +708,8 @@ protected double cardinality(long subj, long pred, long obj, long context) throw
// set cursor to min key
keyData.mv_data(keyBuf);
- int rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
- if (rc != 0 || mdb_cmp(txn, dbi, keyData, maxKey) >= 0) {
+ int rc = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
+ if (rc != MDB_SUCCESS || mdb_cmp(txn, dbi, keyData, maxKey) >= 0) {
break;
} else {
Varint.readListUnsigned(keyData.mv_data(), s.minValues);
@@ -717,15 +717,15 @@ protected double cardinality(long subj, long pred, long obj, long context) throw
// set cursor to max key
keyData.mv_data(maxKeyBuf);
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
- if (rc != 0) {
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
+ if (rc != MDB_SUCCESS) {
// directly go to last value
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_LAST));
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_LAST);
} else {
// go to previous value of selected key
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_PREV));
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_PREV);
}
- if (rc == 0) {
+ if (rc == MDB_SUCCESS) {
Varint.readListUnsigned(keyData.mv_data(), s.maxValues);
// this is required to correctly estimate the range size at a later point
s.startValues[s.MAX_BUCKETS] = s.maxValues;
@@ -747,7 +747,7 @@ protected double cardinality(long subj, long pred, long obj, long context) throw
keyData.mv_data(keyBuf);
int currentSamplesCount = 0;
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
while (rc == MDB_SUCCESS && currentSamplesCount < s.MAX_SAMPLES_PER_BUCKET) {
if (mdb_cmp(txn, dbi, keyData, maxKey) >= 0) {
endOfRange = true;
@@ -776,8 +776,8 @@ protected double cardinality(long subj, long pred, long obj, long context) throw
}
}
}
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT));
- if (rc != 0) {
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT);
+ if (rc != MDB_SUCCESS) {
// no more elements are available
endOfRange = true;
}
@@ -873,14 +873,14 @@ public boolean storeTriple(long subj, long pred, long obj, long context, boolean
return recordCache.storeRecord(quad, explicit);
}
- int rc = E(mdb_put(writeTxn, mainIndex.getDB(explicit), keyVal, dataVal, MDB_NOOVERWRITE));
+ int rc = mdb_put(writeTxn, mainIndex.getDB(explicit), keyVal, dataVal, MDB_NOOVERWRITE);
if (rc != MDB_SUCCESS && rc != MDB_KEYEXIST) {
throw new IOException(mdb_strerror(rc));
}
stAdded = rc == MDB_SUCCESS;
boolean foundImplicit = false;
if (explicit && stAdded) {
- foundImplicit = E(mdb_del(writeTxn, mainIndex.getDB(false), keyVal, dataVal)) == MDB_SUCCESS;
+ foundImplicit = mdb_del(writeTxn, mainIndex.getDB(false), keyVal, dataVal) == MDB_SUCCESS;
}
if (stAdded) {
@@ -920,7 +920,7 @@ private void incrementContext(MemoryStack stack, long context) throws IOExceptio
idVal.mv_data(bb);
MDBVal dataVal = MDBVal.calloc(stack);
long newCount = 1;
- if (E(mdb_get(writeTxn, contextsDbi, idVal, dataVal)) == MDB_SUCCESS) {
+ if (mdb_get(writeTxn, contextsDbi, idVal, dataVal) == MDB_SUCCESS) {
// update count
newCount = Varint.readUnsigned(dataVal.mv_data()) + 1;
}
@@ -944,7 +944,7 @@ private boolean decrementContext(MemoryStack stack, long context) throws IOExcep
bb.flip();
idVal.mv_data(bb);
MDBVal dataVal = MDBVal.calloc(stack);
- if (E(mdb_get(writeTxn, contextsDbi, idVal, dataVal)) == MDB_SUCCESS) {
+ if (mdb_get(writeTxn, contextsDbi, idVal, dataVal) == MDB_SUCCESS) {
// update count
long newCount = Varint.readUnsigned(dataVal.mv_data()) - 1;
if (newCount <= 0) {
diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/TxnRecordCache.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/TxnRecordCache.java
index 27aa38d67a8..73dff3fb1a8 100644
--- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/TxnRecordCache.java
+++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/TxnRecordCache.java
@@ -135,9 +135,9 @@ protected boolean update(long[] quad, boolean explicit, boolean add) throws IOEx
keyBuf.flip();
keyVal.mv_data(keyBuf);
- boolean foundExplicit = E(mdb_get(writeTxn, dbiExplicit, keyVal, dataVal)) == MDB_SUCCESS &&
+ boolean foundExplicit = mdb_get(writeTxn, dbiExplicit, keyVal, dataVal) == MDB_SUCCESS &&
(dataVal.mv_data().get(0) & 0b1) != 0;
- boolean foundImplicit = !foundExplicit && E(mdb_get(writeTxn, dbiInferred, keyVal, dataVal)) == MDB_SUCCESS
+ boolean foundImplicit = !foundExplicit && mdb_get(writeTxn, dbiInferred, keyVal, dataVal) == MDB_SUCCESS
&&
(dataVal.mv_data().get(0) & 0b1) != 0;
@@ -197,17 +197,13 @@ protected RecordCacheIterator(int dbi) throws IOException {
}
public Record next() {
- try {
- if (E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT)) == MDB_SUCCESS) {
- Varint.readListUnsigned(keyData.mv_data(), quad);
- byte op = valueData.mv_data().get(0);
- Record r = new Record();
- r.quad = quad;
- r.add = op == 1;
- return r;
- }
- } catch (IOException e) {
- throw new SailException(e);
+ if (mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT) == MDB_SUCCESS) {
+ Varint.readListUnsigned(keyData.mv_data(), quad);
+ byte op = valueData.mv_data().get(0);
+ Record r = new Record();
+ r.quad = quad;
+ r.add = op == 1;
+ return r;
}
close();
return null;
diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java
index 9242309f420..a0ef94ce123 100644
--- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java
+++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java
@@ -214,13 +214,13 @@ class ValueStore extends AbstractValueFactory {
// set cursor after max ID
keyData.mv_data(stack.bytes(new byte[] { ID_KEY, (byte) 0xFF }));
MDBVal valueData = MDBVal.calloc(stack);
- int rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
- if (rc != 0) {
+ int rc = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
+ if (rc != MDB_SUCCESS) {
// directly go to last value
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_LAST));
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_LAST);
} else {
// go to previous value of selected key
- rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_PREV));
+ rc = mdb_cursor_get(cursor, keyData, valueData, MDB_PREV);
}
if (rc == MDB_SUCCESS && keyData.mv_data().get(0) == ID_KEY) {
// remove lower 2 type bits
@@ -257,7 +257,7 @@ private void logValues() throws IOException {
// set cursor to min key
keyData.mv_data(stack.bytes(new byte[] { ID_KEY }));
MDBVal valueData = MDBVal.calloc(stack);
- int rc = E(mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE));
+ int rc = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
while (rc == MDB_SUCCESS && keyData.mv_data().get(0) == ID_KEY) {
long id = data2id(keyData.mv_data());
try {
@@ -373,7 +373,7 @@ private long nextId(byte type) throws IOException {
E(mdb_cursor_del(cursor, 0));
return value;
}
- freeIdsAvailable = E(mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT)) == MDB_SUCCESS;
+ freeIdsAvailable = mdb_cursor_get(cursor, keyData, valueData, MDB_NEXT) == MDB_SUCCESS;
return null;
} finally {
if (cursor != 0) {
@@ -429,7 +429,7 @@ protected byte[] getData(long id) throws IOException {
MDBVal keyData = MDBVal.calloc(stack);
keyData.mv_data(id2data(idBuffer(stack), id).flip());
MDBVal valueData = MDBVal.calloc(stack);
- if (E(mdb_get(txn, dbi, keyData, valueData)) == MDB_SUCCESS) {
+ if (mdb_get(txn, dbi, keyData, valueData) == MDB_SUCCESS) {
byte[] valueBytes = new byte[valueData.mv_data().remaining()];
valueData.mv_data().get(valueBytes);
return valueBytes;
@@ -616,7 +616,7 @@ private void incrementRefCount(MemoryStack stack, long writeTxn, byte[] data) th
MDBVal dataVal = MDBVal.calloc(stack);
idVal.mv_data(idBuffer(stack).put(ID_KEY).put(data, 1, idLength).flip());
long newCount = 1;
- if (E(mdb_get(writeTxn, refCountsDbi, idVal, dataVal)) == MDB_SUCCESS) {
+ if (mdb_get(writeTxn, refCountsDbi, idVal, dataVal) == MDB_SUCCESS) {
// update count
newCount = Varint.readUnsigned(dataVal.mv_data()) + 1;
}
@@ -638,7 +638,7 @@ private boolean decrementRefCount(MemoryStack stack, long writeTxn, ByteBuffer i
MDBVal idVal = MDBVal.calloc(stack);
idVal.mv_data(idBb);
MDBVal dataVal = MDBVal.calloc(stack);
- if (E(mdb_get(writeTxn, refCountsDbi, idVal, dataVal)) == MDB_SUCCESS) {
+ if (mdb_get(writeTxn, refCountsDbi, idVal, dataVal) == MDB_SUCCESS) {
// update count
long newCount = Varint.readUnsigned(dataVal.mv_data()) - 1;
if (newCount <= 0) {
@@ -664,7 +664,7 @@ private long findId(byte[] data, boolean create) throws IOException {
MDBVal dataVal = MDBVal.calloc(stack);
dataVal.mv_data(stack.bytes(data));
MDBVal idVal = MDBVal.calloc(stack);
- if (E(mdb_get(txn, dbi, dataVal, idVal)) == MDB_SUCCESS) {
+ if (mdb_get(txn, dbi, dataVal, idVal) == MDB_SUCCESS) {
return data2id(idVal.mv_data());
}
if (!create) {
@@ -702,10 +702,9 @@ private long findId(byte[] data, boolean create) throws IOException {
MDBVal dataVal = MDBVal.calloc(stack);
// ID of first value is directly stored with hash as key
- if (E(mdb_get(txn, dbi, hashVal, dataVal)) == MDB_SUCCESS) {
+ if (mdb_get(txn, dbi, hashVal, dataVal) == MDB_SUCCESS) {
idVal.mv_data(dataVal.mv_data());
- if (E(mdb_get(txn, dbi, idVal, dataVal)) == MDB_SUCCESS &&
- dataVal.mv_data().compareTo(dataBb) == 0) {
+ if (mdb_get(txn, dbi, idVal, dataVal) == MDB_SUCCESS && dataVal.mv_data().compareTo(dataBb) == 0) {
return data2id(idVal.mv_data());
}
} else {
@@ -745,7 +744,7 @@ private long findId(byte[] data, boolean create) throws IOException {
cursor = pp.get(0);
// iterate all entries for hash value
- if (E(mdb_cursor_get(cursor, hashVal, dataVal, MDB_SET_RANGE)) == MDB_SUCCESS) {
+ if (mdb_cursor_get(cursor, hashVal, dataVal, MDB_SET_RANGE) == MDB_SUCCESS) {
do {
if (compareRegion(hashVal.mv_data(), 0, hashBb, 0, hashLength) != 0) {
break;
@@ -755,12 +754,12 @@ private long findId(byte[] data, boolean create) throws IOException {
ByteBuffer hashIdBb = hashVal.mv_data();
hashIdBb.position(hashLength);
idVal.mv_data(hashIdBb);
- if (E(mdb_get(txn, dbi, idVal, dataVal)) == MDB_SUCCESS
+ if (mdb_get(txn, dbi, idVal, dataVal) == MDB_SUCCESS
&& dataVal.mv_data().compareTo(dataBb) == 0) {
// id was found if stored value is equal to requested value
return data2id(hashIdBb);
}
- } while (E(mdb_cursor_get(cursor, hashVal, dataVal, MDB_NEXT)) == MDB_SUCCESS);
+ } while (mdb_cursor_get(cursor, hashVal, dataVal, MDB_NEXT) == MDB_SUCCESS);
}
} finally {
if (cursor != 0) {
@@ -959,7 +958,7 @@ public void gcIds(Collection ids, Collection nextIds) throws IOExcep
revIdVal.mv_data(id2data(revIdBb, id).flip());
// check if id has internal references and therefore cannot be deleted
idVal.mv_data(revIdBb.slice().position(revLength));
- if (E(mdb_get(writeTxn, refCountsDbi, idVal, dataVal)) == MDB_SUCCESS) {
+ if (mdb_get(writeTxn, refCountsDbi, idVal, dataVal) == MDB_SUCCESS) {
continue;
}
// mark id as unused
@@ -998,10 +997,9 @@ protected void deleteValueToIdMappings(MemoryStack stack, long txn, Collection
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-lucene-api
RDF4J: Lucene Sail API
diff --git a/core/sail/lucene/pom.xml b/core/sail/lucene/pom.xml
index 9426ef7b6c7..0bf14bb2dc4 100644
--- a/core/sail/lucene/pom.xml
+++ b/core/sail/lucene/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-lucene
RDF4J: Lucene Sail Index
diff --git a/core/sail/memory/pom.xml b/core/sail/memory/pom.xml
index 1ad15a58094..ec77c2ff18d 100644
--- a/core/sail/memory/pom.xml
+++ b/core/sail/memory/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-memory
RDF4J: MemoryStore
diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemorySailStore.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemorySailStore.java
index 8dfcaeb4f0d..47676926f39 100644
--- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemorySailStore.java
+++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemorySailStore.java
@@ -22,9 +22,10 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;
-import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.lang3.time.StopWatch;
+import org.eclipse.rdf4j.common.concurrent.locks.ExclusiveReentrantLockManager;
+import org.eclipse.rdf4j.common.concurrent.locks.Lock;
import org.eclipse.rdf4j.common.concurrent.locks.diagnostics.ConcurrentCleaner;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.common.iteration.CloseableIteratorIteration;
@@ -135,7 +136,7 @@ class MemorySailStore implements SailStore {
/**
* Lock manager used to prevent concurrent writes.
*/
- private final ReentrantLock txnLockManager = new ReentrantLock();
+ private final ExclusiveReentrantLockManager txnLockManager = new ExclusiveReentrantLockManager();
/**
* Cleanup thread that removes deprecated statements when no other threads are accessing this list. Seee
@@ -569,8 +570,7 @@ private final class MemorySailSink implements SailSink {
private int nextSnapshot;
private Set observations;
-
- private volatile boolean txnLock;
+ private volatile Lock txnLock;
private boolean requireCleanup;
@@ -583,6 +583,7 @@ public MemorySailSink(boolean explicit, boolean serializable) throws SailExcepti
this.serializable = Integer.MAX_VALUE;
this.reservedSnapshot = null;
}
+
}
@Override
@@ -593,7 +594,7 @@ public String toString() {
} else {
sb.append("inferred ");
}
- if (txnLock) {
+ if (txnLock != null) {
sb.append("snapshot ").append(nextSnapshot);
} else {
sb.append(super.toString());
@@ -632,18 +633,17 @@ public synchronized void prepare() throws SailException {
}
}
}
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
@Override
public synchronized void flush() throws SailException {
- if (txnLock) {
+ if (txnLock != null && txnLock.isActive()) {
invalidateCache();
currentSnapshot = Math.max(currentSnapshot, nextSnapshot);
if (requireCleanup) {
scheduleSnapshotCleanup();
}
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
}
}
@@ -668,16 +668,10 @@ public void close() {
}
synchronized private void releaseLock() {
- if (txnLock) {
- try {
- txnLock = false;
- txnLockManager.unlock();
- } catch (IllegalMonitorStateException t) {
- txnLock = true;
- throw new SailException("Failed to release lock from thread " + Thread.currentThread()
- + " because it was locked by another thread.", t);
- }
-
+ if (txnLock != null) {
+ assert txnLock.isActive();
+ txnLock.release();
+ txnLock = null;
}
}
@@ -685,21 +679,21 @@ synchronized private void releaseLock() {
public synchronized void setNamespace(String prefix, String name) {
acquireExclusiveTransactionLock();
namespaceStore.setNamespace(prefix, name);
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
@Override
public synchronized void removeNamespace(String prefix) {
acquireExclusiveTransactionLock();
namespaceStore.removeNamespace(prefix);
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
@Override
public synchronized void clearNamespaces() {
acquireExclusiveTransactionLock();
namespaceStore.clear();
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
@Override
@@ -735,7 +729,7 @@ public synchronized void clear(Resource... contexts) {
} catch (InterruptedException e) {
throw convertToSailException(e);
}
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
@Override
@@ -747,7 +741,7 @@ public synchronized void approve(Resource subj, IRI pred, Value obj, Resource ct
} catch (InterruptedException e) {
throw convertToSailException(e);
}
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
@Override
@@ -762,7 +756,7 @@ public synchronized void approveAll(Set approved, Set appro
} catch (InterruptedException e) {
throw convertToSailException(e);
}
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
@Override
@@ -774,7 +768,7 @@ public synchronized void deprecateAll(Set deprecated) {
for (Statement statement : deprecated) {
innerDeprecate(statement, nextSnapshot);
}
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
@Override
@@ -783,7 +777,7 @@ public synchronized void deprecate(Statement statement) throws SailException {
invalidateCache();
requireCleanup = true;
innerDeprecate(statement, nextSnapshot);
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
+
}
private void innerDeprecate(Statement statement, int nextSnapshot) {
@@ -817,16 +811,15 @@ private void innerDeprecate(Statement statement, int nextSnapshot) {
}
private void acquireExclusiveTransactionLock() throws SailException {
- if (!txnLock) {
+ if (txnLock == null) {
synchronized (this) {
- if (!txnLock) {
+ if (txnLock == null) {
try {
- txnLockManager.lockInterruptibly();
+ txnLock = txnLockManager.getExclusiveLock();
+ nextSnapshot = currentSnapshot + 1;
} catch (InterruptedException e) {
throw convertToSailException(e);
}
- nextSnapshot = currentSnapshot + 1;
- txnLock = true;
}
}
@@ -929,7 +922,6 @@ public boolean deprecateByQuery(Resource subj, IRI pred, Value obj, Resource[] c
throw convertToSailException(e);
}
invalidateCache();
- assert txnLock && txnLockManager.isHeldByCurrentThread() : "Should still be holding lock";
return deprecated;
}
diff --git a/core/sail/model/pom.xml b/core/sail/model/pom.xml
index 775203f4869..a4593e109d3 100644
--- a/core/sail/model/pom.xml
+++ b/core/sail/model/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-model
RDF4J: Sail Model
diff --git a/core/sail/nativerdf/pom.xml b/core/sail/nativerdf/pom.xml
index 08f174ebb0c..d143946697f 100644
--- a/core/sail/nativerdf/pom.xml
+++ b/core/sail/nativerdf/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail-nativerdf
RDF4J: NativeStore
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/NativeStatementIterator.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/NativeStatementIterator.java
index 6d8c84cfa9c..29b803e6cb5 100644
--- a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/NativeStatementIterator.java
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/NativeStatementIterator.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.rdf4j.sail.nativerdf;
+import static org.eclipse.rdf4j.sail.nativerdf.NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES;
+
import java.io.IOException;
import org.eclipse.rdf4j.common.io.ByteArrayUtil;
@@ -20,6 +22,11 @@
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.sail.nativerdf.btree.RecordIterator;
+import org.eclipse.rdf4j.sail.nativerdf.model.CorruptIRI;
+import org.eclipse.rdf4j.sail.nativerdf.model.CorruptIRIOrBNode;
+import org.eclipse.rdf4j.sail.nativerdf.model.CorruptUnknownValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A statement iterator that wraps a RecordIterator containing statement records and translates these records to
@@ -27,6 +34,8 @@
*/
class NativeStatementIterator extends LookAheadIteration {
+ private static final Logger logger = LoggerFactory.getLogger(NativeStatementIterator.class);
+
/*-----------*
* Variables *
*-----------*/
@@ -54,17 +63,23 @@ public NativeStatementIterator(RecordIterator btreeIter, ValueStore valueStore)
@Override
public Statement getNextElement() throws SailException {
try {
- byte[] nextValue = btreeIter.next();
+ byte[] nextValue;
+ try {
+ nextValue = btreeIter.next();
+ } catch (AssertionError | Exception e) {
+ logger.error("Error while reading next value from btree iterator for {}", btreeIter.toString(), e);
+ throw e;
+ }
if (nextValue == null) {
return null;
}
int subjID = ByteArrayUtil.getInt(nextValue, TripleStore.SUBJ_IDX);
- Resource subj = (Resource) valueStore.getValue(subjID);
+ Resource subj = valueStore.getResource(subjID);
int predID = ByteArrayUtil.getInt(nextValue, TripleStore.PRED_IDX);
- IRI pred = (IRI) valueStore.getValue(predID);
+ IRI pred = valueStore.getIRI(predID);
int objID = ByteArrayUtil.getInt(nextValue, TripleStore.OBJ_IDX);
Value obj = valueStore.getValue(objID);
@@ -72,7 +87,18 @@ public Statement getNextElement() throws SailException {
Resource context = null;
int contextID = ByteArrayUtil.getInt(nextValue, TripleStore.CONTEXT_IDX);
if (contextID != 0) {
- context = (Resource) valueStore.getValue(contextID);
+ context = valueStore.getResource(contextID);
+ }
+ if (SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES) {
+ if (subj == null) {
+ subj = new CorruptIRIOrBNode(valueStore.getRevision(), subjID, null);
+ }
+ if (pred == null) {
+ pred = new CorruptIRI(valueStore.getRevision(), predID, null, null);
+ }
+ if (obj == null) {
+ obj = new CorruptUnknownValue(valueStore.getRevision(), objID, null);
+ }
}
return valueStore.createStatement(subj, pred, obj, context);
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/NativeStore.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/NativeStore.java
index c82bca9d4d9..e156083b8ef 100644
--- a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/NativeStore.java
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/NativeStore.java
@@ -24,6 +24,7 @@
import org.apache.commons.io.FileUtils;
import org.eclipse.rdf4j.collection.factory.api.CollectionFactory;
import org.eclipse.rdf4j.collection.factory.mapdb.MapDb3CollectionFactory;
+import org.eclipse.rdf4j.common.annotation.InternalUseOnly;
import org.eclipse.rdf4j.common.concurrent.locks.Lock;
import org.eclipse.rdf4j.common.concurrent.locks.LockManager;
import org.eclipse.rdf4j.common.io.MavenUtil;
@@ -62,6 +63,17 @@ public class NativeStore extends AbstractNotifyingSail implements FederatedServi
private static final String VERSION = MavenUtil.loadVersion("org.eclipse.rdf4j", "rdf4j-sail-nativerdf", "devel");
+ /**
+ * Do not throw an exception when corrupt data is detected. Instead, try to return as much data as possible.
+ *
+ * Variable can be set through the system property
+ * org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes.
+ */
+ @InternalUseOnly
+ public static boolean SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES = "true"
+ .equalsIgnoreCase(
+ System.getProperty("org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes"));;
+
private static final Cleaner REMOVE_STORES_USED_FOR_MEMORY_OVERFLOW = Cleaner.create();
/**
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/TripleStore.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/TripleStore.java
index c4bc52cd318..3c060af663d 100644
--- a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/TripleStore.java
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/TripleStore.java
@@ -287,9 +287,71 @@ private Set parseIndexSpecList(String indexSpecStr) throws SailException
}
private void initIndexes(Set indexSpecs) throws IOException {
+
+ HashSet invalidIndexes = new HashSet<>();
+
for (String fieldSeq : indexSpecs) {
logger.trace("Initializing index '{}'...", fieldSeq);
- indexes.add(new TripleIndex(fieldSeq));
+ try {
+ indexes.add(new TripleIndex(fieldSeq, false));
+ } catch (Exception e) {
+ if (NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES) {
+ invalidIndexes.add(fieldSeq);
+ logger.warn("Ignoring index because it failed to initialize index '{}'", fieldSeq, e);
+ } else {
+ logger.error(
+ "Failed to initialize index '{}', consider setting org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes to true.",
+ fieldSeq, e);
+ throw e;
+ }
+
+ }
+
+ }
+
+ if (NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES) {
+ indexSpecs.removeAll(invalidIndexes);
+ }
+
+ List emptyIndexes = new ArrayList<>();
+ List nonEmptyIndexes = new ArrayList<>();
+
+ checkIfIndexesAreEmptyOrNot(nonEmptyIndexes, emptyIndexes);
+
+ if (!emptyIndexes.isEmpty() && !nonEmptyIndexes.isEmpty()) {
+ if (NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES) {
+ indexes.removeAll(emptyIndexes);
+ } else {
+ for (TripleIndex index : emptyIndexes) {
+ throw new IOException("Index '" + new String(index.getFieldSeq())
+ + "' is unexpectedly empty while other indexes are not. Consider setting the system property org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes to true. Index file: "
+ + index.getBTree().getFile().getAbsolutePath());
+ }
+ }
+ }
+
+ }
+
+ private void checkIfIndexesAreEmptyOrNot(List nonEmptyIndexes, List emptyIndexes)
+ throws IOException {
+ for (TripleIndex index : indexes) {
+ try (RecordIterator recordIterator = index.getBTree().iterateAll()) {
+ try {
+ byte[] next = recordIterator.next();
+ if (next != null) {
+ next = recordIterator.next();
+ if (next != null) {
+ nonEmptyIndexes.add(index);
+ } else {
+ emptyIndexes.add(index);
+ }
+ } else {
+ emptyIndexes.add(index);
+ }
+ } catch (Throwable ignored) {
+ emptyIndexes.add(index);
+ }
+ }
}
}
@@ -355,7 +417,7 @@ private void reindex(Set currentIndexSpecs, Set newIndexSpecs) t
for (String fieldSeq : addedIndexSpecs) {
logger.debug("Initializing new index '{}'...", fieldSeq);
- TripleIndex addedIndex = new TripleIndex(fieldSeq);
+ TripleIndex addedIndex = new TripleIndex(fieldSeq, true);
BTree addedBTree = null;
RecordIterator sourceIter = null;
try {
@@ -1122,7 +1184,17 @@ private class TripleIndex {
private final BTree btree;
- public TripleIndex(String fieldSeq) throws IOException {
+ public TripleIndex(String fieldSeq, boolean deleteExistingIndexFile) throws IOException {
+ if (deleteExistingIndexFile) {
+ File indexFile = new File(dir, getFilenamePrefix(fieldSeq) + ".dat");
+ if (indexFile.exists()) {
+ indexFile.delete();
+ }
+ File alloxFile = new File(dir, getFilenamePrefix(fieldSeq) + ".alloc");
+ if (alloxFile.exists()) {
+ alloxFile.delete();
+ }
+ }
tripleComparator = new TripleComparator(fieldSeq);
btree = new BTree(dir, getFilenamePrefix(fieldSeq), 2048, RECORD_LENGTH, tripleComparator, forceSync);
}
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/ValueStore.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/ValueStore.java
index 7193c7e8342..37787ac610c 100644
--- a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/ValueStore.java
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/ValueStore.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.rdf4j.sail.nativerdf;
+import static org.eclipse.rdf4j.sail.nativerdf.NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES;
+
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -33,11 +35,18 @@
import org.eclipse.rdf4j.model.vocabulary.XSD;
import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.sail.nativerdf.datastore.DataStore;
+import org.eclipse.rdf4j.sail.nativerdf.model.CorruptIRI;
+import org.eclipse.rdf4j.sail.nativerdf.model.CorruptIRIOrBNode;
+import org.eclipse.rdf4j.sail.nativerdf.model.CorruptLiteral;
+import org.eclipse.rdf4j.sail.nativerdf.model.CorruptUnknownValue;
+import org.eclipse.rdf4j.sail.nativerdf.model.CorruptValue;
import org.eclipse.rdf4j.sail.nativerdf.model.NativeBNode;
import org.eclipse.rdf4j.sail.nativerdf.model.NativeIRI;
import org.eclipse.rdf4j.sail.nativerdf.model.NativeLiteral;
import org.eclipse.rdf4j.sail.nativerdf.model.NativeResource;
import org.eclipse.rdf4j.sail.nativerdf.model.NativeValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* File-based indexed storage and retrieval of RDF values. ValueStore maps RDF values to integer IDs and vice-versa.
@@ -49,9 +58,7 @@
@InternalUseOnly
public class ValueStore extends SimpleValueFactory {
- /*-----------*
- * Constants *
- *-----------*/
+ private static final Logger logger = LoggerFactory.getLogger(ValueStore.class);
/**
* The default value cache size.
@@ -146,6 +153,7 @@ public ValueStore(File dataDir, boolean forceSync, int valueCacheSize, int value
namespaceIDCache = new ConcurrentCache<>(namespaceIDCacheSize);
setNewRevision();
+
}
/*---------*
@@ -180,6 +188,7 @@ public Lock getReadLock() throws InterruptedException {
* @throws IOException If an I/O error occurred.
*/
public NativeValue getValue(int id) throws IOException {
+
// Check value cache
Integer cacheID = id;
NativeValue resultValue = valueCache.get(cacheID);
@@ -191,12 +200,62 @@ public NativeValue getValue(int id) throws IOException {
if (data != null) {
resultValue = data2value(id, data);
- // Store value in cache
- valueCache.put(cacheID, resultValue);
+ if (!(resultValue instanceof CorruptValue)) {
+ // Store value in cache
+ valueCache.put(cacheID, resultValue);
+ }
}
}
return resultValue;
+
+ }
+
+ /**
+ * Gets the Resource for the specified ID.
+ *
+ * @param id A value ID.
+ * @return The Resource for the ID, or null no such value could be found.
+ * @throws IOException If an I/O error occurred.
+ */
+ public T getResource(int id) throws IOException {
+
+ NativeValue resultValue = getValue(id);
+
+ if (resultValue != null && !(resultValue instanceof Resource)) {
+ if (SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES && resultValue instanceof CorruptValue) {
+ return (T) new CorruptIRIOrBNode(revision, id, ((CorruptValue) resultValue).getData());
+ }
+ logger.warn(
+ "NativeStore is possibly corrupt. To attempt to repair or retrieve the data, read the documentation on http://rdf4j.org about the system property org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes");
+ }
+
+ return (T) resultValue;
+ }
+
+ /**
+ * Gets the IRI for the specified ID.
+ *
+ * @param id A value ID.
+ * @return The IRI for the ID, or null no such value could be found.
+ * @throws IOException If an I/O error occurred.
+ */
+ public T getIRI(int id) throws IOException {
+
+ NativeValue resultValue = getValue(id);
+
+ if (resultValue != null && !(resultValue instanceof IRI)) {
+ if (SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES && resultValue instanceof CorruptValue) {
+ if (resultValue instanceof CorruptIRI) {
+ return (T) resultValue;
+ }
+ return (T) new CorruptIRI(revision, id, null, ((CorruptValue) resultValue).getData());
+ }
+ logger.warn(
+ "NativeStore is possibly corrupt. To attempt to repair or retrieve the data, read the documentation on http://rdf4j.org about the system property org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes");
+ }
+
+ return (T) resultValue;
}
/**
@@ -526,6 +585,14 @@ private boolean isNamespaceData(byte[] data) {
}
private NativeValue data2value(int id, byte[] data) throws IOException {
+ if (data.length == 0) {
+ if (SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES) {
+ logger.error("Soft fail on corrupt data: Empty data array for value with id {}", id);
+ return new CorruptUnknownValue(revision, id, data);
+ }
+ throw new SailException("Empty data array for value with id " + id
+ + " consider setting the system property org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes to true");
+ }
switch (data[0]) {
case URI_VALUE:
return data2uri(id, data);
@@ -534,17 +601,35 @@ private NativeValue data2value(int id, byte[] data) throws IOException {
case LITERAL_VALUE:
return data2literal(id, data);
default:
- throw new IllegalArgumentException("Invalid type " + data[0] + " for value with id " + id);
+ if (SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES) {
+ logger.error("Soft fail on corrupt data: Invalid type {} for value with id {}", data[0], id);
+ return new CorruptUnknownValue(revision, id, data);
+ }
+ throw new SailException("Invalid type " + data[0] + " for value with id " + id
+ + " consider setting the system property org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes to true");
}
}
- private NativeIRI data2uri(int id, byte[] data) throws IOException {
- int nsID = ByteArrayUtil.getInt(data, 1);
- String namespace = getNamespace(nsID);
+ private T data2uri(int id, byte[] data) throws IOException {
+ String namespace = null;
- String localName = new String(data, 5, data.length - 5, StandardCharsets.UTF_8);
+ try {
+ int nsID = ByteArrayUtil.getInt(data, 1);
+ namespace = getNamespace(nsID);
+
+ String localName = new String(data, 5, data.length - 5, StandardCharsets.UTF_8);
+
+ return (T) new NativeIRI(revision, namespace, localName, id);
+ } catch (Throwable e) {
+ if (SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES
+ && (e instanceof Exception || e instanceof AssertionError)) {
+ return (T) new CorruptIRI(revision, id, namespace, data);
+ }
+ logger.warn(
+ "NativeStore is possibly corrupt. To attempt to repair or retrieve the data, read the documentation on http://rdf4j.org about the system property org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes");
+ throw e;
+ }
- return new NativeIRI(revision, namespace, localName, id);
}
private NativeBNode data2bnode(int id, byte[] data) {
@@ -552,31 +637,40 @@ private NativeBNode data2bnode(int id, byte[] data) {
return new NativeBNode(revision, nodeID, id);
}
- private NativeLiteral data2literal(int id, byte[] data) throws IOException {
- // Get datatype
- int datatypeID = ByteArrayUtil.getInt(data, 1);
- IRI datatype = null;
- if (datatypeID != NativeValue.UNKNOWN_ID) {
- datatype = (IRI) getValue(datatypeID);
- }
+ private T data2literal(int id, byte[] data) throws IOException {
+ try {
+ // Get datatype
+ int datatypeID = ByteArrayUtil.getInt(data, 1);
+ IRI datatype = null;
+ if (datatypeID != NativeValue.UNKNOWN_ID) {
+ datatype = (IRI) getValue(datatypeID);
+ }
- // Get language tag
- String lang = null;
- int langLength = data[5];
- if (langLength > 0) {
- lang = new String(data, 6, langLength, StandardCharsets.UTF_8);
- }
+ // Get language tag
+ String lang = null;
+ int langLength = data[5];
+ if (langLength > 0) {
+ lang = new String(data, 6, langLength, StandardCharsets.UTF_8);
+ }
- // Get label
- String label = new String(data, 6 + langLength, data.length - 6 - langLength, StandardCharsets.UTF_8);
+ // Get label
+ String label = new String(data, 6 + langLength, data.length - 6 - langLength, StandardCharsets.UTF_8);
- if (lang != null) {
- return new NativeLiteral(revision, label, lang, id);
- } else if (datatype != null) {
- return new NativeLiteral(revision, label, datatype, id);
- } else {
- return new NativeLiteral(revision, label, CoreDatatype.XSD.STRING, id);
+ if (lang != null) {
+ return (T) new NativeLiteral(revision, label, lang, id);
+ } else if (datatype != null) {
+ return (T) new NativeLiteral(revision, label, datatype, id);
+ } else {
+ return (T) new NativeLiteral(revision, label, CoreDatatype.XSD.STRING, id);
+ }
+ } catch (Throwable e) {
+ if (SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES
+ && (e instanceof Exception || e instanceof AssertionError)) {
+ return (T) new CorruptLiteral(revision, id, data);
+ }
+ throw e;
}
+
}
private String data2namespace(byte[] data) {
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/btree/BTree.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/btree/BTree.java
index 078f0f8601d..b297d940ea3 100644
--- a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/btree/BTree.java
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/btree/BTree.java
@@ -25,6 +25,7 @@
import org.eclipse.rdf4j.common.io.ByteArrayUtil;
import org.eclipse.rdf4j.common.io.NioFile;
import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -292,6 +293,13 @@ public BTree(File dataDir, String filenamePrefix, int blockSize, int valueSize,
this.valueSize = buf.getInt();
this.rootNodeID = buf.getInt();
+ if (rootNodeID == 0 && NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES) {
+ if (nioFile.size() > blockSize) {
+ throw new SailException("Root node ID is 0 but file is not empty. Btree may be corrupt. File: "
+ + file.getAbsolutePath());
+ }
+ }
+
if (Arrays.equals(MAGIC_NUMBER, magicNumber)) {
if (version > FILE_FORMAT_VERSION) {
throw new IOException("Unable to read BTree file " + file + "; it uses a newer file format");
@@ -1117,4 +1125,11 @@ public void print(PrintStream out) throws IOException {
out.println("#values = " + valueCount);
out.println("---end of BTree file---");
}
+
+ @Override
+ public String toString() {
+ return "BTree{" +
+ "file=" + getFile() +
+ '}';
+ }
}
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/btree/RangeIterator.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/btree/RangeIterator.java
index d7f1617b292..e6a6a3847e6 100644
--- a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/btree/RangeIterator.java
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/btree/RangeIterator.java
@@ -422,4 +422,11 @@ public boolean nodeMergedWith(Node sourceNode, Node targetNode, int mergeIdx) th
return deregister;
}
+
+ @Override
+ public String toString() {
+ return "RangeIterator{" +
+ "tree=" + tree +
+ '}';
+ }
}
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/datastore/DataFile.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/datastore/DataFile.java
index d369c1649cf..73e9c349de7 100644
--- a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/datastore/DataFile.java
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/datastore/DataFile.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.rdf4j.sail.nativerdf.datastore;
+import static org.eclipse.rdf4j.sail.nativerdf.NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES;
+
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
@@ -18,6 +20,8 @@
import java.util.NoSuchElementException;
import org.eclipse.rdf4j.common.io.NioFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Class supplying access to a data file. A data file stores data sequentially. Each entry starts with the entry's
@@ -27,6 +31,8 @@
*/
public class DataFile implements Closeable {
+ private static final Logger logger = LoggerFactory.getLogger(DataFile.class);
+
/*-----------*
* Constants *
*-----------*/
@@ -197,29 +203,51 @@ public byte[] getData(long offset) throws IOException {
(data[2] << 8) & 0x0000ff00 |
(data[3]) & 0x000000ff;
- // We have either managed to read enough data and can return the required subset of the data, or we have read
- // too little so we need to execute another read to get the correct data.
- if (dataLength <= data.length - 4) {
+ // If the data length is larger than 750MB, we are likely reading the wrong data. Probably data corruption. The
+ // limit of 750MB was chosen based on results from experimenting in the NativeSailStoreCorruptionTest class.
+ if (dataLength > 128 * 1024 * 1024) {
+ if (SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES) {
+ logger.error(
+ "Data length is {}MB which is larger than 750MB. This is likely data corruption. Truncating length to 32 MB.",
+ dataLength / ((1024 * 1024)));
+ dataLength = 32 * 1024 * 1024;
+ }
+ }
- // adjust the approximate average with 1 part actual length and 99 parts previous average up to a sensible
- // max of 200
- dataLengthApproximateAverage = (int) (Math.min(200,
- ((dataLengthApproximateAverage / 100.0) * 99) + (dataLength / 100.0)));
+ try {
- return Arrays.copyOfRange(data, 4, dataLength + 4);
+ // We have either managed to read enough data and can return the required subset of the data, or we have
+ // read
+ // too little so we need to execute another read to get the correct data.
+ if (dataLength <= data.length - 4) {
- } else {
+ // adjust the approximate average with 1 part actual length and 99 parts previous average up to a
+ // sensible
+ // max of 200
+ dataLengthApproximateAverage = (int) (Math.min(200,
+ ((dataLengthApproximateAverage / 100.0) * 99) + (dataLength / 100.0)));
- // adjust the approximate average, but favour the actual dataLength since dataLength predictions misses are
- // costly
- dataLengthApproximateAverage = Math.min(200, (dataLengthApproximateAverage + dataLength) / 2);
+ return Arrays.copyOfRange(data, 4, dataLength + 4);
- // we didn't read enough data so we need to execute a new read
- data = new byte[dataLength];
- buf = ByteBuffer.wrap(data);
- nioFile.read(buf, offset + 4L);
+ } else {
- return data;
+ // adjust the approximate average, but favour the actual dataLength since dataLength predictions misses
+ // are costly
+ dataLengthApproximateAverage = Math.min(200, (dataLengthApproximateAverage + dataLength) / 2);
+
+ // we didn't read enough data so we need to execute a new read
+ data = new byte[dataLength];
+ buf = ByteBuffer.wrap(data);
+ nioFile.read(buf, offset + 4L);
+
+ return data;
+ }
+ } catch (OutOfMemoryError e) {
+ if (dataLength > 128 * 1024 * 1024) {
+ logger.error(
+ "Trying to read large amounts of data may be a sign of data corruption. Consider setting the system property org.eclipse.rdf4j.sail.nativerdf.softFailOnCorruptDataAndRepairIndexes to true");
+ }
+ throw e;
}
}
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptIRI.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptIRI.java
new file mode 100644
index 00000000000..71816d29e4d
--- /dev/null
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptIRI.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Eclipse RDF4J contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Distribution License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.rdf4j.sail.nativerdf.model;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.codec.binary.Hex;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.eclipse.rdf4j.sail.nativerdf.ValueStoreRevision;
+
+import com.google.common.net.UrlEscapers;
+
+/**
+ * CorruptIRI is used when a NativeValue cannot be read from the ValueStore and if soft failure is enabled
+ *
+ * @see NativeStore#SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES .
+ *
+ * @author Håvard M. Ottestad
+ */
+public class CorruptIRI extends CorruptValue implements IRI {
+
+ private static final long serialVersionUID = -6995615243794525852L;
+ private final String namespace;
+
+ public CorruptIRI(ValueStoreRevision revision, int internalID, String namespace, byte[] data) {
+ super(revision, internalID, data);
+ this.namespace = namespace;
+ }
+
+ @Override
+ public String toString() {
+ return stringValue();
+ }
+
+ public String stringValue() {
+ try {
+ return getNamespace() + ":" + getLocalName();
+ } catch (Throwable ignored) {
+ }
+
+ return "CorruptIRI_with_ID_" + getInternalID();
+ }
+
+ @Override
+ public String getNamespace() {
+ if (namespace != null && !namespace.isEmpty()) {
+ return namespace;
+ }
+ return "urn:CorruptIRI:";
+ }
+
+ @Override
+ public String getLocalName() {
+ byte[] data = getData();
+ if (data != null && data.length < 1024) {
+ try {
+ String localName = new String(data, 5, data.length - 5, StandardCharsets.UTF_8);
+ return "CORRUPT_" + UrlEscapers.urlPathSegmentEscaper().escape(localName);
+ } catch (Throwable ignored) {
+ }
+
+ return "CORRUPT_" + Hex.encodeHexString(data);
+ }
+
+ return "CORRUPT";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o instanceof CorruptIRI && getInternalID() != NativeValue.UNKNOWN_ID) {
+ CorruptIRI otherCorruptValue = (CorruptIRI) o;
+
+ if (otherCorruptValue.getInternalID() != NativeValue.UNKNOWN_ID
+ && getValueStoreRevision().equals(otherCorruptValue.getValueStoreRevision())) {
+ // CorruptValue is from the same revision of the same native store with both IDs set
+ return getInternalID() == otherCorruptValue.getInternalID();
+ }
+ }
+
+ return super.equals(o);
+ }
+
+}
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptIRIOrBNode.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptIRIOrBNode.java
new file mode 100644
index 00000000000..83cdb9e6658
--- /dev/null
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptIRIOrBNode.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Eclipse RDF4J contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Distribution License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.rdf4j.sail.nativerdf.model;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.codec.binary.Hex;
+import org.eclipse.rdf4j.model.BNode;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.eclipse.rdf4j.sail.nativerdf.ValueStoreRevision;
+
+import com.google.common.net.UrlEscapers;
+
+/**
+ * CorruptIRIOrBNode is used when a NativeValue cannot be read from the ValueStore and if soft failure is enabled
+ *
+ * @see NativeStore#SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES .
+ *
+ * @author Håvard M. Ottestad
+ */
+public class CorruptIRIOrBNode extends CorruptValue implements IRI, BNode {
+
+ private static final long serialVersionUID = 3709784393454516043L;
+
+ public CorruptIRIOrBNode(ValueStoreRevision revision, int internalID, byte[] data) {
+ super(revision, internalID, data);
+ }
+
+ @Override
+ public String toString() {
+ return stringValue();
+ }
+
+ public String stringValue() {
+ try {
+ return getNamespace() + ":" + getLocalName();
+ } catch (Throwable ignored) {
+ }
+
+ return "CorruptIRIOrBNode_with_ID_" + getInternalID();
+ }
+
+ @Override
+ public String getNamespace() {
+ return "urn:CorruptIRIOrBNode:";
+ }
+
+ @Override
+ public String getLocalName() {
+ byte[] data = getData();
+ if (data != null && data.length < 1024) {
+ try {
+ String localName = new String(data, 5, data.length - 5, StandardCharsets.UTF_8);
+ return "CORRUPT_" + UrlEscapers.urlPathSegmentEscaper().escape(localName);
+ } catch (Throwable ignored) {
+ }
+
+ return "CORRUPT_" + Hex.encodeHexString(data);
+ }
+
+ return "CORRUPT";
+ }
+
+ @Override
+ public String getID() {
+ return "";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o instanceof CorruptIRIOrBNode && getInternalID() != NativeValue.UNKNOWN_ID) {
+ CorruptIRIOrBNode otherCorruptValue = (CorruptIRIOrBNode) o;
+
+ if (otherCorruptValue.getInternalID() != NativeValue.UNKNOWN_ID
+ && getValueStoreRevision().equals(otherCorruptValue.getValueStoreRevision())) {
+ // CorruptValue is from the same revision of the same native store with both IDs set
+ return getInternalID() == otherCorruptValue.getInternalID();
+ }
+ }
+
+ return super.equals(o);
+ }
+
+}
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptLiteral.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptLiteral.java
new file mode 100644
index 00000000000..eb6b2587c25
--- /dev/null
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptLiteral.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Eclipse RDF4J contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Distribution License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.rdf4j.sail.nativerdf.model;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.base.CoreDatatype;
+import org.eclipse.rdf4j.model.util.Values;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.eclipse.rdf4j.sail.nativerdf.ValueStoreRevision;
+
+/**
+ * CorruptLiteral is used when a NativeValue cannot be read from the ValueStore and if soft failure is enabled
+ *
+ * @see NativeStore#SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES .
+ *
+ * @author Håvard M. Ottestad
+ */
+public class CorruptLiteral extends CorruptValue implements Literal {
+
+ private static final long serialVersionUID = -2510885288827542623L;
+
+ private static final IRI CORRUPT = Values.iri("urn:corrupt");
+
+ public CorruptLiteral(ValueStoreRevision revision, int internalID, byte[] data) {
+ super(revision, internalID, data);
+ }
+
+ public String stringValue() {
+ return "CorruptLiteral_with_ID_" + getInternalID();
+ }
+
+ @Override
+ public String getLabel() {
+ byte[] data = getData();
+ try {
+ if (data != null && data.length < 1024) {
+ return "CorruptUnknownValue with ID " + getInternalID() + " with possible data: "
+ + new String(data, StandardCharsets.UTF_8);
+ }
+ } catch (Throwable ignored) {
+ }
+ return "CorruptUnknownValue_with_ID_" + getInternalID();
+ }
+
+ @Override
+ public Optional getLanguage() {
+ return Optional.empty();
+ }
+
+ @Override
+ public IRI getDatatype() {
+ return CORRUPT;
+ }
+
+ @Override
+ public boolean booleanValue() {
+ return false;
+ }
+
+ @Override
+ public byte byteValue() {
+ return 0;
+ }
+
+ @Override
+ public short shortValue() {
+ return 0;
+ }
+
+ @Override
+ public int intValue() {
+ return 0;
+ }
+
+ @Override
+ public long longValue() {
+ return 0;
+ }
+
+ @Override
+ public BigInteger integerValue() {
+ return null;
+ }
+
+ @Override
+ public BigDecimal decimalValue() {
+ return null;
+ }
+
+ @Override
+ public float floatValue() {
+ return 0;
+ }
+
+ @Override
+ public double doubleValue() {
+ return 0;
+ }
+
+ @Override
+ public XMLGregorianCalendar calendarValue() {
+ return null;
+ }
+
+ @Override
+ public CoreDatatype getCoreDatatype() {
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o instanceof CorruptLiteral && getInternalID() != NativeValue.UNKNOWN_ID) {
+ CorruptLiteral otherCorruptValue = (CorruptLiteral) o;
+
+ if (otherCorruptValue.getInternalID() != NativeValue.UNKNOWN_ID
+ && getValueStoreRevision().equals(otherCorruptValue.getValueStoreRevision())) {
+ // CorruptValue is from the same revision of the same native store with both IDs set
+ return getInternalID() == otherCorruptValue.getInternalID();
+ }
+ }
+
+ return super.equals(o);
+ }
+
+}
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptUnknownValue.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptUnknownValue.java
new file mode 100644
index 00000000000..ea200b55fa5
--- /dev/null
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptUnknownValue.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Eclipse RDF4J contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Distribution License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.rdf4j.sail.nativerdf.model;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.base.CoreDatatype;
+import org.eclipse.rdf4j.model.vocabulary.XSD;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.eclipse.rdf4j.sail.nativerdf.ValueStoreRevision;
+
+/**
+ * CorruptUnknownValue is used when a NativeValue cannot be read from the ValueStore and if soft failure is enabled
+ *
+ * @see NativeStore#SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES .
+ *
+ * @author Håvard M. Ottestad
+ */
+public class CorruptUnknownValue extends CorruptValue implements Literal {
+
+ private static final long serialVersionUID = -6650510290226676279L;
+
+ public CorruptUnknownValue(ValueStoreRevision revision, int internalID, byte[] data) {
+ super(revision, internalID, data);
+ }
+
+ @Override
+ public String getLabel() {
+ byte[] data = getData();
+ try {
+ if (data != null && data.length < 1024) {
+ return "CorruptUnknownValue with ID " + getInternalID() + " with possible data: "
+ + new String(data, StandardCharsets.UTF_8);
+ }
+ } catch (Throwable ignored) {
+ }
+ return "CorruptUnknownValue_with_ID_" + getInternalID();
+ }
+
+ @Override
+ public Optional getLanguage() {
+ return Optional.empty();
+ }
+
+ @Override
+ public IRI getDatatype() {
+ return XSD.STRING;
+ }
+
+ @Override
+ public boolean booleanValue() {
+ return false;
+ }
+
+ @Override
+ public byte byteValue() {
+ return 0;
+ }
+
+ @Override
+ public short shortValue() {
+ return 0;
+ }
+
+ @Override
+ public int intValue() {
+ return 0;
+ }
+
+ @Override
+ public long longValue() {
+ return 0;
+ }
+
+ @Override
+ public BigInteger integerValue() {
+ return null;
+ }
+
+ @Override
+ public BigDecimal decimalValue() {
+ return null;
+ }
+
+ @Override
+ public float floatValue() {
+ return 0;
+ }
+
+ @Override
+ public double doubleValue() {
+ return 0;
+ }
+
+ @Override
+ public XMLGregorianCalendar calendarValue() {
+ return null;
+ }
+
+ @Override
+ public CoreDatatype getCoreDatatype() {
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o instanceof CorruptUnknownValue && getInternalID() != NativeValue.UNKNOWN_ID) {
+ CorruptUnknownValue otherCorruptValue = (CorruptUnknownValue) o;
+
+ if (otherCorruptValue.getInternalID() != NativeValue.UNKNOWN_ID
+ && getValueStoreRevision().equals(otherCorruptValue.getValueStoreRevision())) {
+ // CorruptValue is from the same revision of the same native store with both IDs set
+ return getInternalID() == otherCorruptValue.getInternalID();
+ }
+ }
+
+ return super.equals(o);
+ }
+
+}
diff --git a/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptValue.java b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptValue.java
new file mode 100644
index 00000000000..94028b5c579
--- /dev/null
+++ b/core/sail/nativerdf/src/main/java/org/eclipse/rdf4j/sail/nativerdf/model/CorruptValue.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Eclipse RDF4J contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Distribution License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.rdf4j.sail.nativerdf.model;
+
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.eclipse.rdf4j.sail.nativerdf.ValueStoreRevision;
+
+/**
+ * CorruptValue is used when a NativeValue cannot be read from the ValueStore and if soft failure is enabled
+ *
+ * @see NativeStore#SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES .
+ *
+ * There is no method isCorruptValue() as it would exist for a "regular" implementation of NativeValue. Since
+ * CorruptValue is only to be used in exceptional situations, the recommended way of checking for it is using
+ * "instanceof".
+ *
+ * @author Hannes Ebner
+ */
+public class CorruptValue implements NativeValue {
+
+ private static final long serialVersionUID = 8829067881854394802L;
+
+ private final byte[] data;
+ private volatile ValueStoreRevision revision;
+ private volatile int internalID;
+
+ public CorruptValue(ValueStoreRevision revision, int internalID, byte[] data) {
+ setInternalID(internalID, revision);
+ this.data = data;
+ }
+
+ @Override
+ public void setInternalID(int internalID, ValueStoreRevision revision) {
+ this.internalID = internalID;
+ this.revision = revision;
+ }
+
+ @Override
+ public ValueStoreRevision getValueStoreRevision() {
+ return revision;
+ }
+
+ @Override
+ public int getInternalID() {
+ return internalID;
+ }
+
+ public String stringValue() {
+ return "CorruptValue_with_ID_" + internalID;
+ }
+
+ /**
+ * Returns the bytes that were read from the ValueStore for this value's internalID. Since the value is corrupt the
+ * data may be null or an empty array.
+ *
+ * @return null, empty array or corrupt data
+ */
+ public byte[] getData() {
+ return data;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o instanceof CorruptValue && internalID != NativeValue.UNKNOWN_ID) {
+ CorruptValue otherCorruptValue = (CorruptValue) o;
+
+ if (otherCorruptValue.internalID != NativeValue.UNKNOWN_ID && revision.equals(otherCorruptValue.revision)) {
+ // CorruptValue is from the same revision of the same native store with both IDs set
+ return internalID == otherCorruptValue.internalID;
+ }
+ }
+
+ return super.equals(o);
+ }
+
+}
diff --git a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeSailStoreCorruptionTest.java b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeSailStoreCorruptionTest.java
new file mode 100644
index 00000000000..12119ceb50b
--- /dev/null
+++ b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeSailStoreCorruptionTest.java
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Eclipse RDF4J contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Distribution License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.util.Values;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.RDFS;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.RepositoryResult;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.Rio;
+import org.jetbrains.annotations.NotNull;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tests how the NativeStore handles corruption in the data files.
+ */
+public class NativeSailStoreCorruptionTest {
+
+ private static final Logger logger = LoggerFactory.getLogger(NativeSailStoreCorruptionTest.class);
+
+ @TempDir
+ File tempFolder;
+
+ protected Repository repo;
+
+ protected final ValueFactory F = SimpleValueFactory.getInstance();
+
+ private File dataDir;
+
+ @BeforeEach
+ public void before() throws IOException {
+ this.dataDir = new File(tempFolder, "dbmodel");
+ dataDir.mkdir();
+ repo = new SailRepository(new NativeStore(dataDir, "spoc,posc"));
+ repo.init();
+
+ IRI CTX_1 = F.createIRI("urn:one");
+ IRI CTX_2 = F.createIRI("urn:two");
+
+ Statement S0 = F.createStatement(F.createIRI("http://example.org/a0"), RDFS.LABEL, F.createLiteral("zero"));
+ Statement S1 = F.createStatement(F.createIRI("http://example.org/b1"), RDFS.LABEL, F.createLiteral("one"));
+ Statement S2 = F.createStatement(F.createIRI("http://example.org/c2"), RDFS.LABEL, F.createLiteral("two"));
+ Statement S3 = F.createStatement(Values.bnode(), RDF.TYPE, Values.bnode());
+ Statement S4 = F.createStatement(F.createIRI("http://example.org/c2"), RDFS.LABEL,
+ F.createLiteral("two", "en"));
+ Statement S5 = F.createStatement(F.createIRI("http://example.org/c2"), RDFS.LABEL, F.createLiteral(1.2));
+
+ try (RepositoryConnection conn = repo.getConnection()) {
+ conn.add(S0);
+ conn.add(S1, CTX_1);
+ conn.add(S2, CTX_2);
+ conn.add(S2, CTX_2);
+ conn.add(S3, CTX_2);
+ conn.add(S4, CTX_2);
+ conn.add(S5, CTX_2);
+ }
+ backupFile(dataDir, "values.dat");
+ backupFile(dataDir, "values.id");
+ backupFile(dataDir, "values.hash");
+ backupFile(dataDir, "namespaces.dat");
+ backupFile(dataDir, "contexts.dat");
+ backupFile(dataDir, "triples-posc.alloc");
+ backupFile(dataDir, "triples-posc.dat");
+ backupFile(dataDir, "triples-spoc.alloc");
+ backupFile(dataDir, "triples-spoc.dat");
+
+ NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES = true;
+
+ }
+
+ public static void overwriteByteInFile(File valuesFile, long pos, int newVal) throws IOException {
+
+ // Use RandomAccessFile in "rw" mode to read and write to the file
+ try (RandomAccessFile raf = new RandomAccessFile(valuesFile, "rw")) {
+ // Get the length of the file
+ long fileLength = raf.length();
+
+ // Check if the position is within the file bounds
+ if (pos >= fileLength) {
+ throw new IOException(
+ "Attempt to write outside the existing file bounds: " + pos + " >= " + fileLength);
+ }
+
+ // Move the file pointer to byte position 32
+ raf.seek(pos);
+
+ // Write the byte value 0x0 at the current position
+ raf.writeByte(newVal);
+ }
+ }
+
+ public static void backupFile(File dataDir, String s) throws IOException {
+ File valuesFile = new File(dataDir, s);
+ File backupFile = new File(dataDir, s + ".bak");
+
+ if (!valuesFile.exists()) {
+ throw new IOException(s + " does not exist and cannot be backed up.");
+ }
+
+ // Copy values.dat to values.dat.bak
+ Files.copy(valuesFile.toPath(), backupFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ public static void restoreFile(File dataDir, String s) throws IOException {
+ File valuesFile = new File(dataDir, s);
+ File backupFile = new File(dataDir, s + ".bak");
+
+ if (!backupFile.exists()) {
+ throw new IOException("Backup file " + s + ".bak does not exist.");
+ }
+
+ // Copy values.dat.bak back to values.dat
+ Files.copy(backupFile.toPath(), valuesFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ @Test
+ public void testCorruptValuesDatFileNamespace() throws IOException {
+ repo.shutDown();
+
+ overwriteByteInFile(new File(dataDir, "values.dat"), 12, 0x0);
+
+ repo.init();
+
+ List list = getStatements();
+ assertEquals(6, list.size());
+ }
+
+ @Test
+ public void testCorruptValuesDatFileNamespaceDatatype() throws IOException {
+ repo.shutDown();
+
+ overwriteByteInFile(new File(dataDir, "values.dat"), 96, 0x0);
+
+ repo.init();
+
+ List list = getStatements();
+ assertEquals(6, list.size());
+ }
+
+ @Test
+ public void testCorruptValuesDatFileEmptyDataArrayError() throws IOException {
+ repo.shutDown();
+
+ overwriteByteInFile(new File(dataDir, "values.dat"), 173, 0x0);
+
+ repo.init();
+
+ List list = getStatements();
+ assertEquals(6, list.size());
+ }
+
+ @Test
+ public void testCorruptValuesDatFileInvalidTypeError() throws IOException {
+ repo.shutDown();
+
+ overwriteByteInFile(new File(dataDir, "values.dat"), 174, 0x0);
+
+ repo.init();
+
+ List list = getStatements();
+ assertEquals(6, list.size());
+ }
+
+ @Test
+ public void testCorruptValuesDatFileEntireValuesDatFile() throws IOException {
+ for (int i = 4; i < 437; i++) {
+ logger.debug("Corrupting byte at position " + i);
+ repo.shutDown();
+ restoreFile(dataDir, "values.dat");
+
+ overwriteByteInFile(new File(dataDir, "values.dat"), i, 0x0);
+
+ repo.init();
+
+ List list = getStatements();
+ assertEquals(6, list.size());
+ }
+ }
+
+ @Test
+ public void testCorruptLastByteOfValuesDatFile() throws IOException {
+ repo.shutDown();
+ File valuesFile = new File(dataDir, "values.dat");
+ long fileSize = valuesFile.length();
+
+ overwriteByteInFile(valuesFile, fileSize - 1, 0x0);
+
+ repo.init();
+
+ List list = getStatements();
+ assertEquals(6, list.size());
+ }
+
+ @Test
+ public void testCorruptValuesIdFile() throws IOException {
+ repo.shutDown();
+ File valuesIdFile = new File(dataDir, "values.id");
+ long fileSize = valuesIdFile.length();
+
+ for (long i = 4; i < fileSize; i++) {
+ restoreFile(dataDir, "values.id");
+ overwriteByteInFile(valuesIdFile, i, 0x0);
+ repo.init();
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ repo.shutDown();
+ }
+ }
+
+ @Test
+ public void testCorruptValuesHashFile() throws IOException {
+ repo.shutDown();
+ String file = "values.hash";
+ File nativeStoreFile = new File(dataDir, file);
+ long fileSize = nativeStoreFile.length();
+
+ for (long i = 4; i < fileSize; i++) {
+ restoreFile(dataDir, file);
+ overwriteByteInFile(nativeStoreFile, i, 0x0);
+ repo.init();
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ repo.shutDown();
+ }
+ }
+
+ @Test
+ public void testCorruptValuesNamespacesFile() throws IOException {
+ repo.shutDown();
+ String file = "namespaces.dat";
+ File nativeStoreFile = new File(dataDir, file);
+ long fileSize = nativeStoreFile.length();
+
+ for (long i = 4; i < fileSize; i++) {
+ restoreFile(dataDir, file);
+ overwriteByteInFile(nativeStoreFile, i, 0x0);
+ repo.init();
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ repo.shutDown();
+ }
+ }
+
+ @Test
+ public void testCorruptValuesContextsFile() throws IOException {
+ repo.shutDown();
+ String file = "contexts.dat";
+ File nativeStoreFile = new File(dataDir, file);
+ long fileSize = nativeStoreFile.length();
+
+ for (long i = 4; i < fileSize; i++) {
+ restoreFile(dataDir, file);
+ overwriteByteInFile(nativeStoreFile, i, 0x0);
+ repo.init();
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ repo.shutDown();
+ }
+ }
+
+ @Test
+ public void testCorruptValuesPoscAllocFile() throws IOException {
+ repo.shutDown();
+ String file = "triples-posc.alloc";
+ File nativeStoreFile = new File(dataDir, file);
+ long fileSize = nativeStoreFile.length();
+
+ for (long i = 4; i < fileSize; i++) {
+ restoreFile(dataDir, file);
+ overwriteByteInFile(nativeStoreFile, i, 0x0);
+ repo.init();
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ repo.shutDown();
+ }
+ }
+
+ @Test
+ public void testCorruptValuesPoscDataFile() throws IOException {
+ repo.shutDown();
+ String file = "triples-posc.dat";
+ File nativeStoreFile = new File(dataDir, file);
+ long fileSize = nativeStoreFile.length();
+
+ for (long i = 4; i < fileSize; i++) {
+ NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES = true;
+ restoreFile(dataDir, file);
+ overwriteByteInFile(nativeStoreFile, i, 0x0);
+ repo.init();
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ repo.shutDown();
+ }
+ }
+
+ @Test
+ public void testCorruptValuesSpocAllocFile() throws IOException {
+ repo.shutDown();
+ String file = "triples-spoc.alloc";
+ File nativeStoreFile = new File(dataDir, file);
+ long fileSize = nativeStoreFile.length();
+
+ for (long i = 4; i < fileSize; i++) {
+ restoreFile(dataDir, file);
+ overwriteByteInFile(nativeStoreFile, i, 0x0);
+ repo.init();
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ repo.shutDown();
+ }
+ }
+
+ @Test
+ public void testCorruptValuesSpocDataFile() throws IOException {
+ repo.shutDown();
+ String file = "triples-spoc.dat";
+ File nativeStoreFile = new File(dataDir, file);
+ long fileSize = nativeStoreFile.length();
+
+ for (long i = 4; i < fileSize; i++) {
+ restoreFile(dataDir, file);
+ overwriteByteInFile(nativeStoreFile, i, 0x0);
+ repo.init();
+ try {
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ } catch (Throwable ignored) {
+ repo.shutDown();
+ nativeStoreFile.delete();
+ repo.init();
+ List list = getStatements();
+ assertEquals(6, list.size(), "Failed at byte position " + i);
+ }
+
+ repo.shutDown();
+ }
+ }
+
+ @NotNull
+ private List getStatements() {
+ List list = new ArrayList<>();
+
+ try (RepositoryConnection conn = repo.getConnection()) {
+ StringWriter stringWriter = new StringWriter();
+ RDFWriter writer = Rio.createWriter(RDFFormat.NQUADS, stringWriter);
+ conn.export(writer);
+ logger.debug(stringWriter.toString());
+ try (RepositoryResult statements = conn.getStatements(null, null, null, false)) {
+ while (statements.hasNext()) {
+ Statement next = statements.next();
+ list.add(next);
+ logger.debug(next.toString());
+ }
+ }
+ return list;
+ }
+ }
+
+ @AfterEach
+ public void after() throws IOException {
+ NativeStore.SOFT_FAIL_ON_CORRUPT_DATA_AND_REPAIR_INDEXES = false;
+ repo.shutDown();
+ }
+}
diff --git a/core/sail/pom.xml b/core/sail/pom.xml
index fb588e4341e..6e5664ecf74 100644
--- a/core/sail/pom.xml
+++ b/core/sail/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-core
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-sail
pom
diff --git a/core/sail/shacl/pom.xml b/core/sail/shacl/pom.xml
index 02282768527..8028c286e2c 100644
--- a/core/sail/shacl/pom.xml
+++ b/core/sail/shacl/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4j
rdf4j-sail
- 5.0.1-SNAPSHOT
+ 5.0.4-SNAPSHOT
rdf4j-shacl
RDF4J: SHACL
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailBaseConfiguration.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailBaseConfiguration.java
index 1256eb8a3f8..cc43e3e6015 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailBaseConfiguration.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailBaseConfiguration.java
@@ -27,7 +27,7 @@ abstract class ShaclSailBaseConfiguration extends NotifyingSailWrapper {
private static final Logger logger = LoggerFactory.getLogger(ShaclSailBaseConfiguration.class);
// Field used to control if the new SPARQL based validation should be enabled or disabled. Enabled by default.
- final boolean sparqlValidation;
+ boolean sparqlValidation;
private boolean parallelValidation = ShaclSailConfig.PARALLEL_VALIDATION_DEFAULT;
private boolean logValidationPlans = ShaclSailConfig.LOG_VALIDATION_PLANS_DEFAULT;
@@ -375,4 +375,5 @@ public Set getShapesGraphs() {
public void setShapesGraphs(Set shapesGraphs) {
this.shapesGraphs = shapesGraphs;
}
+
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java
index 83e2da56ad7..829fdd91766 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java
@@ -524,8 +524,9 @@ private ValidationReport performValidation(List shapes, boolea
sail.isPerformanceLogging())),
sail.isGlobalLogValidationExecution(), sail.isLogValidationViolations(),
sail.getEffectiveValidationResultsLimitPerConstraint(), sail.isPerformanceLogging(),
- logger
- ))
+ sail.isLogValidationPlans(),
+ logger,
+ connectionsGroup))
.filter(ShapeValidationContainer::hasPlanNode)
.map(validationContainer -> validationContainer::performValidation);
@@ -738,24 +739,7 @@ synchronized public void close() throws SailException {
if (getWrappedConnection() instanceof AbstractSailConnection) {
AbstractSailConnection abstractSailConnection = (AbstractSailConnection) getWrappedConnection();
- if (Thread.currentThread() != abstractSailConnection.getOwner()) {
- Thread owner = abstractSailConnection.getOwner();
- logger.error(
- "Closing connection from a different thread than the one that opened it. Connections should not be shared between threads. Opened by "
- + owner + " closed by " + Thread.currentThread(),
- new Throwable("Throwable used for stacktrace"));
- owner.interrupt();
- try {
- owner.join(1000);
- if (owner.isAlive()) {
- logger.error("Interrupted thread {} but thread is still alive after 1000 ms!", owner);
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new SailException(e);
- }
- }
-
+ abstractSailConnection.waitForOtherOperations(true);
}
try {
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclValidator.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclValidator.java
index f6222b4117b..ed9442c0ef7 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclValidator.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclValidator.java
@@ -115,8 +115,8 @@ private static ValidationReport performValidation(List shapes,
() -> contextWithShape.getShape()
.generatePlans(connectionsGroup,
new ValidationSettings(contextWithShape.getDataGraph(), false, true, false)),
- false, false, 1000, false, logger
- )
+ false, false, 1000, false, false, logger,
+ connectionsGroup)
)
.filter(ShapeValidationContainer::hasPlanNode)
.map(ShapeValidationContainer::performValidation)
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShapeValidationContainer.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShapeValidationContainer.java
index 463f16dba50..9545135c8e9 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShapeValidationContainer.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShapeValidationContainer.java
@@ -11,6 +11,7 @@
package org.eclipse.rdf4j.sail.shacl;
+import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -23,6 +24,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.ValidationExecutionLogger;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.ValidationTuple;
import org.eclipse.rdf4j.sail.shacl.results.lazy.ValidationResultIterator;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
class ShapeValidationContainer {
@@ -36,7 +38,7 @@ class ShapeValidationContainer {
public ShapeValidationContainer(Shape shape, Supplier planNodeSupplier, boolean logValidationExecution,
boolean logValidationViolations, long effectiveValidationResultsLimitPerConstraint,
- boolean performanceLogging, Logger logger) {
+ boolean performanceLogging, boolean logValidationPlans, Logger logger, ConnectionsGroup connectionsGroup) {
this.shape = shape;
this.logValidationViolations = logValidationViolations;
this.effectiveValidationResultsLimitPerConstraint = effectiveValidationResultsLimitPerConstraint;
@@ -44,6 +46,56 @@ public ShapeValidationContainer(Shape shape, Supplier planNodeSupplier
this.logger = logger;
try {
PlanNode planNode = planNodeSupplier.get();
+
+ if (logValidationPlans) {
+
+ StringBuilder planAsGraphvizDot = new StringBuilder();
+
+ planAsGraphvizDot.append(
+ "rank1 [style=invisible];\n" +
+ "rank2 [style=invisible];\n" +
+ "\n" +
+ "rank1 -> rank2 [color=white];\n");
+
+ planAsGraphvizDot.append("{\n")
+ .append("\trank = same;\n")
+ .append("\trank2 -> ")
+ .append(System.identityHashCode(connectionsGroup.getBaseConnection()))
+ .append(" -> ")
+ .append(System.identityHashCode(connectionsGroup.getAddedStatements()))
+ .append(" -> ")
+ .append(System.identityHashCode(connectionsGroup.getRemovedStatements()))
+ .append(" [ style=invis ];\n")
+ .append("\trankdir = LR;\n")
+ .append("}\n");
+
+ planAsGraphvizDot.append(System.identityHashCode(connectionsGroup.getBaseConnection()))
+ .append(" [label=\"")
+ .append("BaseConnection")
+ .append("\" fillcolor=\"#CACADB\", style=filled];")
+ .append("\n");
+
+ planAsGraphvizDot.append(System.identityHashCode(connectionsGroup.getAddedStatements()))
+ .append(" [label=\"")
+ .append("AddedStatements")
+ .append("\" fillcolor=\"#CEDBCA\", style=filled];")
+ .append("\n");
+
+ planAsGraphvizDot.append(System.identityHashCode(connectionsGroup.getRemovedStatements()))
+ .append(" [label=\"")
+ .append("RemovedStatements")
+ .append("\" fillcolor=\"#DBCFC9r\", style=filled];")
+ .append("\n");
+
+ planNode.getPlanAsGraphvizDot(planAsGraphvizDot);
+
+ String[] split = planAsGraphvizDot.toString().split("\n");
+ planAsGraphvizDot = new StringBuilder();
+ Arrays.stream(split).map(s -> "\t" + s + "\n").forEach(planAsGraphvizDot::append);
+
+ logger.info("Plan as Graphviz dot:\ndigraph G {\n{}}", planAsGraphvizDot);
+ }
+
this.validationExecutionLogger = ValidationExecutionLogger
.getInstance(logValidationExecution);
if (!(planNode.isGuaranteedEmpty())) {
@@ -82,12 +134,13 @@ public ValidationResultIterator performValidation() {
validationResults = new ValidationResultIterator(iterator, effectiveValidationResultsLimitPerConstraint);
return validationResults;
} catch (Throwable e) {
- logger.warn("Error validating SHACL Shape {}", shape.getId(), e);
- logger.warn("Error validating SHACL Shape\n{}", shape, e);
+ logger.warn("Internal error while trying to validate SHACL Shape {}", shape.getId(), e);
+ logger.warn("Internal error while trying to validate SHACL Shape\n{}", shape, e);
if (e instanceof Error) {
throw e;
}
- throw new SailException("Error validating SHACL Shape " + shape.getId() + "\n" + shape, e);
+ throw new SailException(
+ "Internal error while trying to validate SHACL Shape " + shape.getId() + "\n" + shape, e);
} finally {
handlePostLogging(before, validationResults);
}
@@ -112,7 +165,6 @@ private void handlePostLogging(long before, ValidationResultIterator validationR
}
if (validationResults != null) {
-
if (performanceLogging) {
long after = System.currentTimeMillis();
logger.info("Execution of plan took {} ms for:\n{}\n",
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/SourceConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/SourceConstraintComponent.java
index a382d502efe..dc6dd7a0678 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/SourceConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/SourceConstraintComponent.java
@@ -16,53 +16,53 @@
import org.eclipse.rdf4j.model.vocabulary.SHACL;
public enum SourceConstraintComponent {
- MaxCountConstraintComponent(SHACL.MAX_COUNT_CONSTRAINT_COMPONENT, false),
- MinCountConstraintComponent(SHACL.MIN_COUNT_CONSTRAINT_COMPONENT, false),
-
- DatatypeConstraintComponent(SHACL.DATATYPE_CONSTRAINT_COMPONENT, true),
- NodeKindConstraintComponent(SHACL.NODE_KIND_CONSTRAINT_COMPONENT, true),
- ClassConstraintComponent(SHACL.CLASS_CONSTRAINT_COMPONENT, true),
-
- PatternConstraintComponent(SHACL.PATTERN_CONSTRAINT_COMPONENT, true),
- UniqueLangConstraintComponent(SHACL.UNIQUE_LANG_CONSTRAINT_COMPONENT, false),
- LanguageInConstraintComponent(SHACL.LANGUAGE_IN_CONSTRAINT_COMPONENT, true),
- MaxLengthConstraintComponent(SHACL.MAX_LENGTH_CONSTRAINT_COMPONENT, true),
- MinLengthConstraintComponent(SHACL.MIN_LENGTH_CONSTRAINT_COMPONENT, true),
-
- InConstraintComponent(SHACL.IN_CONSTRAINT_COMPONENT, true),
- HasValueConstraintComponent(SHACL.HAS_VALUE_CONSTRAINT_COMPONENT, false),
- HasValueInConstraintComponent(DASH.HasValueInConstraintComponent, false),
- ClosedConstraintComponent(SHACL.CLOSED_CONSTRAINT_COMPONENT, true),
-
- MinExclusiveConstraintComponent(SHACL.MIN_EXCLUSIVE_CONSTRAINT_COMPONENT, true),
- MaxExclusiveConstraintComponent(SHACL.MAX_EXCLUSIVE_CONSTRAINT_COMPONENT, true),
- MaxInclusiveConstraintComponent(SHACL.MAX_INCLUSIVE_CONSTRAINT_COMPONENT, true),
- MinInclusiveConstraintComponent(SHACL.MIN_INCLUSIVE_CONSTRAINT_COMPONENT, true),
-
- AndConstraintComponent(SHACL.AND_CONSTRAINT_COMPONENT, true),
- OrConstraintComponent(SHACL.OR_CONSTRAINT_COMPONENT, true),
- NotConstraintComponent(SHACL.NOT_CONSTRAINT_COMPONENT, true),
- XoneConstraintComponent(SHACL.XONE_CONSTRAINT_COMPONENT, true),
-
- DisjointConstraintComponent(SHACL.DISJOINT_CONSTRAINT_COMPONENT, true),
- EqualsConstraintComponent(SHACL.EQUALS_CONSTRAINT_COMPONENT, true),
- LessThanConstraintComponent(SHACL.LESS_THAN_CONSTRAINT_COMPONENT, true),
+ MaxCountConstraintComponent(SHACL.MAX_COUNT_CONSTRAINT_COMPONENT, ProducesValidationResultValue.NEVER),
+ MinCountConstraintComponent(SHACL.MIN_COUNT_CONSTRAINT_COMPONENT, ProducesValidationResultValue.NEVER),
+
+ DatatypeConstraintComponent(SHACL.DATATYPE_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ NodeKindConstraintComponent(SHACL.NODE_KIND_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ ClassConstraintComponent(SHACL.CLASS_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+
+ PatternConstraintComponent(SHACL.PATTERN_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ UniqueLangConstraintComponent(SHACL.UNIQUE_LANG_CONSTRAINT_COMPONENT, ProducesValidationResultValue.NEVER),
+ LanguageInConstraintComponent(SHACL.LANGUAGE_IN_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ MaxLengthConstraintComponent(SHACL.MAX_LENGTH_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ MinLengthConstraintComponent(SHACL.MIN_LENGTH_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+
+ InConstraintComponent(SHACL.IN_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ HasValueConstraintComponent(SHACL.HAS_VALUE_CONSTRAINT_COMPONENT, ProducesValidationResultValue.NEVER),
+ HasValueInConstraintComponent(DASH.HasValueInConstraintComponent, ProducesValidationResultValue.NEVER),
+ ClosedConstraintComponent(SHACL.CLOSED_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+
+ MinExclusiveConstraintComponent(SHACL.MIN_EXCLUSIVE_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ MaxExclusiveConstraintComponent(SHACL.MAX_EXCLUSIVE_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ MaxInclusiveConstraintComponent(SHACL.MAX_INCLUSIVE_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ MinInclusiveConstraintComponent(SHACL.MIN_INCLUSIVE_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+
+ AndConstraintComponent(SHACL.AND_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ OrConstraintComponent(SHACL.OR_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ NotConstraintComponent(SHACL.NOT_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ XoneConstraintComponent(SHACL.XONE_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+
+ DisjointConstraintComponent(SHACL.DISJOINT_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ EqualsConstraintComponent(SHACL.EQUALS_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ LessThanConstraintComponent(SHACL.LESS_THAN_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
LessThanOrEqualsConstraintComponent(SHACL.LESS_THAN_OR_EQUALS_CONSTRAINT_COMPONENT,
- true),
+ ProducesValidationResultValue.ALWAYS),
QualifiedMaxCountConstraintComponent(SHACL.QUALIFIED_MAX_COUNT_CONSTRAINT_COMPONENT,
- false),
+ ProducesValidationResultValue.NEVER),
QualifiedMinCountConstraintComponent(SHACL.QUALIFIED_MIN_COUNT_CONSTRAINT_COMPONENT,
- false),
- NodeConstraintComponent(SHACL.NODE_CONSTRAINT_COMPONENT, true),
- PropertyConstraintComponent(SHACL.PROPERTY_CONSTRAINT_COMPONENT, false),
+ ProducesValidationResultValue.NEVER),
+ NodeConstraintComponent(SHACL.NODE_CONSTRAINT_COMPONENT, ProducesValidationResultValue.ALWAYS),
+ PropertyConstraintComponent(SHACL.PROPERTY_CONSTRAINT_COMPONENT, ProducesValidationResultValue.NEVER),
- SPARQLConstraintComponent(SHACL.SPARQL_CONSTRAINT_COMPONENT, true);
+ SPARQLConstraintComponent(SHACL.SPARQL_CONSTRAINT_COMPONENT, ProducesValidationResultValue.SOMETIMES);
private final IRI iri;
- private final boolean producesValidationResultValue;
+ private final ProducesValidationResultValue producesValidationResultValue;
- SourceConstraintComponent(IRI iri, boolean producesValidationResultValue) {
+ SourceConstraintComponent(IRI iri, ProducesValidationResultValue producesValidationResultValue) {
this.iri = iri;
this.producesValidationResultValue = producesValidationResultValue;
}
@@ -72,6 +72,16 @@ public IRI getIri() {
}
public boolean producesValidationResultValue() {
- return producesValidationResultValue;
+ return producesValidationResultValue != ProducesValidationResultValue.NEVER;
+ }
+
+ public boolean alwaysProducesValidationResultValue() {
+ return producesValidationResultValue == ProducesValidationResultValue.ALWAYS;
+ }
+
+ private enum ProducesValidationResultValue {
+ ALWAYS,
+ NEVER,
+ SOMETIMES
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/NodeShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/NodeShape.java
index 6ec57c5e1f8..0688db2316e 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/NodeShape.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/NodeShape.java
@@ -173,14 +173,15 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
return new ValidationResult(t.getActiveTarget(), t.getActiveTarget(), this,
constraintComponent, getSeverity(), t.getScope(), t.getContexts(),
getContexts());
- });
+ }, connectionsGroup);
}
if (scope == Scope.propertyShape) {
- validationPlanNode = Unique.getInstance(new ShiftToPropertyShape(validationPlanNode), true);
+ validationPlanNode = Unique.getInstance(new ShiftToPropertyShape(validationPlanNode, connectionsGroup),
+ true, connectionsGroup);
}
- union = UnionNode.getInstance(union, validationPlanNode);
+ union = UnionNode.getInstance(connectionsGroup, union, validationPlanNode);
}
return union;
@@ -207,7 +208,7 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
.map(c -> c.getAllTargetsPlan(connectionsGroup, dataGraph, Scope.nodeShape,
new StatementMatcher.StableRandomVariableProvider()))
.distinct()
- .reduce(UnionNode::getInstanceDedupe)
+ .reduce((nodes, nodes2) -> UnionNode.getInstanceDedupe(connectionsGroup, nodes, nodes2))
.orElse(EmptyNode.getInstance());
if (connectionsGroup.getStats().hasRemoved()) {
@@ -216,14 +217,14 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.getPlanNode(connectionsGroup, dataGraph, Scope.nodeShape, true, null);
- planNode = UnionNode.getInstanceDedupe(planNode, planNodeEffectiveTarget);
+ planNode = UnionNode.getInstanceDedupe(connectionsGroup, planNode, planNodeEffectiveTarget);
}
if (scope == Scope.propertyShape) {
- planNode = Unique.getInstance(new ShiftToPropertyShape(planNode), true);
+ planNode = Unique.getInstance(new ShiftToPropertyShape(planNode, connectionsGroup), true, connectionsGroup);
}
- planNode = Unique.getInstance(planNode, false);
+ planNode = Unique.getInstance(planNode, false, connectionsGroup);
return planNode;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java
index 2efcdcb1ac0..5735bf9276d 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java
@@ -236,16 +236,18 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
return new ValidationResult(t.getActiveTarget(), t.getValue(), this,
constraintComponent, getSeverity(), t.getScope(), t.getContexts(),
getContexts());
- });
+ }, connectionsGroup);
}
if (scope == Scope.propertyShape) {
- validationPlanNode = Unique.getInstance(new TargetChainPopper(validationPlanNode), true);
+ validationPlanNode = Unique.getInstance(new TargetChainPopper(validationPlanNode, connectionsGroup),
+ true, connectionsGroup);
} else {
- validationPlanNode = Unique.getInstance(new ShiftToNodeShape(validationPlanNode), true);
+ validationPlanNode = Unique.getInstance(new ShiftToNodeShape(validationPlanNode, connectionsGroup),
+ true, connectionsGroup);
}
- union = UnionNode.getInstance(union, validationPlanNode);
+ union = UnionNode.getInstance(connectionsGroup, union, validationPlanNode);
}
return union;
@@ -258,7 +260,7 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
.map(c -> c.getAllTargetsPlan(connectionsGroup, dataGraph, Scope.propertyShape,
new StatementMatcher.StableRandomVariableProvider()))
.distinct()
- .reduce(UnionNode::getInstanceDedupe)
+ .reduce((nodes, nodes2) -> UnionNode.getInstanceDedupe(connectionsGroup, nodes, nodes2))
.orElse(EmptyNode.getInstance());
if (connectionsGroup.getStats().hasRemoved()) {
@@ -267,16 +269,16 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.getPlanNode(connectionsGroup, dataGraph, Scope.propertyShape, true, null);
- planNode = UnionNode.getInstanceDedupe(planNode, planNodeEffectiveTarget);
+ planNode = UnionNode.getInstanceDedupe(connectionsGroup, planNode, planNodeEffectiveTarget);
}
if (scope == Scope.propertyShape) {
- planNode = Unique.getInstance(new TargetChainPopper(planNode), true);
+ planNode = Unique.getInstance(new TargetChainPopper(planNode, connectionsGroup), true, connectionsGroup);
} else {
- planNode = new ShiftToNodeShape(planNode);
+ planNode = new ShiftToNodeShape(planNode, connectionsGroup);
}
- planNode = Unique.getInstance(planNode, false);
+ planNode = Unique.getInstance(planNode, false, connectionsGroup);
return planNode;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/Shape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/Shape.java
index fb16757fb67..4c3d7db0bb4 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/Shape.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/Shape.java
@@ -422,7 +422,7 @@ public PlanNode generatePlans(ConnectionsGroup connectionsGroup, ValidationSetti
Scope.none)
.getValidationPlan(connectionsGroup.getBaseConnection(), validationSettings.getDataGraph(),
getContexts()),
- this);
+ this, connectionsGroup);
} else {
logger.debug("Use fall back validation approach for bulk validation instead of SPARQL for shape {}",
this);
@@ -436,7 +436,7 @@ public PlanNode generatePlans(ConnectionsGroup connectionsGroup, ValidationSetti
.getAllTargets(connectionsGroup,
validationSettings.getDataGraph(),
this instanceof NodeShape ? Scope.nodeShape : Scope.propertyShape),
- Scope.none), this);
+ Scope.none), this, connectionsGroup);
}
} else if (validationApproach == ValidationApproach.Transactional) {
@@ -447,7 +447,7 @@ public PlanNode generatePlans(ConnectionsGroup connectionsGroup, ValidationSetti
return new SingleCloseablePlanNode(
Shape.this.generateTransactionalValidationPlan(connectionsGroup, validationSettings, null,
Scope.none),
- this);
+ this, connectionsGroup);
} else {
return EmptyNode.getInstance();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/StatementMatcher.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/StatementMatcher.java
index ec04e8e02b5..68daca2381e 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/StatementMatcher.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/StatementMatcher.java
@@ -11,7 +11,9 @@
package org.eclipse.rdf4j.sail.shacl.ast;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -31,10 +33,10 @@ public class StatementMatcher {
private final Variable predicate;
private final Variable extends Value> object;
-// private final Set varNames;
+ // private final Set varNames;
private final Targetable origin;
- private final Set inheritedVarNames;
+ private Set inheritedVarNames;
private List subset = List.of();
@@ -216,11 +218,17 @@ private static String formatForToString(String field, String name, Value value)
private StatementMatcher swap(Variable> existingVariable, Variable> newVariable) {
String subjectName = getSubjectName();
+ String subjectBasename = getSubjectBasename();
Resource subjectValue = getSubjectValue();
+
String predicateName = getPredicateName();
+ String predicateBasename = getPredicateBasename();
IRI predicateValue = getPredicateValue();
+
String objectName = getObjectName();
+ String objectBasename = getObjectBasename();
Value objectValue = getObjectValue();
+
boolean changed = false;
if (Objects.equals(existingVariable.name, subjectName)
@@ -228,6 +236,7 @@ private StatementMatcher swap(Variable> existingVariable, Variable> newVaria
changed = true;
subjectName = newVariable.name;
subjectValue = (Resource) newVariable.value;
+ subjectBasename = newVariable.baseName;
}
if (Objects.equals(existingVariable.name, predicateName)
@@ -235,18 +244,21 @@ private StatementMatcher swap(Variable> existingVariable, Variable> newVaria
changed = true;
predicateName = newVariable.name;
predicateValue = (IRI) newVariable.value;
+ predicateBasename = newVariable.baseName;
}
if (Objects.equals(existingVariable.name, objectName) && Objects.equals(existingVariable.value, objectValue)) {
changed = true;
objectName = newVariable.name;
objectValue = newVariable.value;
+ objectBasename = newVariable.baseName;
}
if (changed) {
assert subset.isEmpty();
- return new StatementMatcher(new Variable<>(subjectName, subjectValue),
- new Variable<>(predicateName, predicateValue), new Variable<>(objectName, objectValue), origin,
+ return new StatementMatcher(new Variable<>(subjectName, subjectValue, subjectBasename),
+ new Variable<>(predicateName, predicateValue, predicateBasename),
+ new Variable<>(objectName, objectValue, objectBasename), origin,
inheritedVarNames);
}
return this;
@@ -268,6 +280,10 @@ public String getSubjectName() {
return subject.name;
}
+ public String getSubjectBasename() {
+ return subject.baseName;
+ }
+
public Resource getSubjectValue() {
return subject.value;
}
@@ -280,6 +296,10 @@ public String getPredicateName() {
return predicate.name;
}
+ public String getPredicateBasename() {
+ return predicate.baseName;
+ }
+
public IRI getPredicateValue() {
return predicate.value;
}
@@ -292,6 +312,10 @@ public String getObjectName() {
return object.name;
}
+ public String getObjectBasename() {
+ return object.baseName;
+ }
+
public Value getObjectValue() {
return object.value;
}
@@ -376,13 +400,13 @@ public String getSparqlValuesDecl(Set varNamesRestriction, boolean addIn
return sb.toString();
}
- public Set getVarNames(Set varNamesRestriction, boolean addInheritedVarNames,
+ public LinkedHashSet getVarNames(Set varNamesRestriction, boolean addInheritedVarNames,
Set varNamesInQueryFragment) {
if (varNamesRestriction.isEmpty()) {
- return Set.of();
+ return new LinkedHashSet<>();
}
- HashSet ret = new HashSet<>();
+ LinkedHashSet ret = new LinkedHashSet<>();
if (subject.name != null && varNamesRestriction.contains(subject.name)
&& varNamesInQueryFragment.contains(subject.name)) {
ret.add(subject.name);
@@ -462,6 +486,26 @@ public boolean hasObject(Variable variable) {
return variable.name.equals(object.name);
}
+ public Set getInheritedVarNames() {
+ return Set.copyOf(inheritedVarNames);
+ }
+
+ public Set getVarNames() {
+ Set varNames = new HashSet<>();
+
+ if (subject.name != null) {
+ varNames.add(subject.name);
+ }
+ if (predicate.name != null) {
+ varNames.add(predicate.name);
+ }
+ if (object.name != null) {
+ varNames.add(object.name);
+ }
+
+ return Collections.unmodifiableSet(varNames);
+ }
+
public static class StableRandomVariableProvider {
// We just need a random base that isn't used elsewhere in the ShaclSail, but we don't want it to be stable so
@@ -485,9 +529,12 @@ public StableRandomVariableProvider(String prefix) {
* increments of one.
*
* @param inputQuery the query string that should be normalized
+ * @param union
* @return a normalized query string
*/
- public static String normalize(String inputQuery) {
+ public static String normalize(String inputQuery, List extends Variable> protectedVars,
+ List union) {
+
if (!inputQuery.contains(BASE)) {
return inputQuery;
}
@@ -513,18 +560,30 @@ public static String normalize(String inputQuery) {
if (lowest == 0 && incrementsOfOne) {
return inputQuery;
}
+ String joinedProtectedVars = protectedVars.stream()
+ .map(Variable::getName)
+ .filter(Objects::nonNull)
+ .filter(s -> s.contains(BASE))
+ .collect(Collectors.joining());
- return normalizeRange(inputQuery, lowest, highest);
+ return normalizeRange(inputQuery, lowest, highest, joinedProtectedVars, union);
}
- private static String normalizeRange(String inputQuery, int lowest, int highest) {
+ private static String normalizeRange(String inputQuery, int lowest, int highest, String joinedProtectedVars,
+ List union) {
String normalizedQuery = inputQuery;
for (int i = 0; i <= highest; i++) {
- if (!normalizedQuery.contains(BASE + i + "_")) {
+ String replacement = BASE + i + "_";
+ if (!normalizedQuery.contains(replacement)) {
for (int j = Math.max(i + 1, lowest); j <= highest; j++) {
- if (normalizedQuery.contains(BASE + j + "_")) {
- normalizedQuery = normalizedQuery.replace(BASE + j + "_", BASE + i + "_");
+ String original = BASE + j + "_";
+ if (normalizedQuery.contains(original)) {
+ if (joinedProtectedVars.contains(original)) {
+ continue;
+ }
+ normalizedQuery = normalizedQuery.replace(original, replacement);
+ replaceInStatementMatcher(union, original, replacement);
break;
}
}
@@ -534,6 +593,13 @@ private static String normalizeRange(String inputQuery, int lowest, int highest)
return normalizedQuery;
}
+ private static void replaceInStatementMatcher(List statementMatchers, String original,
+ String replacement) {
+ for (StatementMatcher statementMatcher : statementMatchers) {
+ statementMatcher.replaceVariableName(original, replacement);
+ }
+ }
+
public Variable next() {
counter++;
@@ -552,6 +618,44 @@ public Variable current() {
}
}
+ private void replaceVariableName(String original, String replacement) {
+
+ if (subject.name != null && subject.name.contains(original)) {
+ subject.name = subject.name.replace(original, replacement);
+ }
+ if (subject.baseName != null && subject.baseName.contains(original)) {
+ subject.baseName = subject.baseName.replace(original, replacement);
+ }
+ if (predicate.name != null && predicate.name.contains(original)) {
+ predicate.name = predicate.name.replace(original, replacement);
+ }
+ if (predicate.baseName != null && predicate.baseName.contains(original)) {
+ predicate.baseName = predicate.baseName.replace(original, replacement);
+ }
+ if (object.name != null && object.name.contains(original)) {
+ object.name = object.name.replace(original, replacement);
+ }
+ if (object.baseName != null && object.baseName.contains(original)) {
+ object.baseName = object.baseName.replace(original, replacement);
+ }
+
+ boolean contains = false;
+ for (String inheritedVarName : inheritedVarNames) {
+ if (inheritedVarName.contains(original)) {
+ contains = true;
+ break;
+ }
+ }
+ if (contains) {
+ HashSet newInheritedVarNames = new HashSet<>();
+ for (String inheritedVarName : inheritedVarNames) {
+ newInheritedVarNames.add(inheritedVarName.replace(original, replacement));
+ }
+ inheritedVarNames = newInheritedVarNames;
+ }
+
+ }
+
public static class Variable {
public static final Variable VALUE = new Variable<>("value");
public static final Variable THIS = new Variable<>("this");
@@ -576,6 +680,12 @@ public Variable(Variable> baseVariable, String name) {
this.baseName = baseVariable.name;
}
+ public Variable(String name, T value, String baseName) {
+ this.name = name;
+ this.value = value;
+ this.baseName = baseName;
+ }
+
public Variable(T value) {
this.value = value;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/ValidationQuery.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/ValidationQuery.java
index 64fe604f64d..f3b6fdd26b6 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/ValidationQuery.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/ValidationQuery.java
@@ -83,7 +83,7 @@ public ValidationQuery(Collection namespaces, String query, List getFilterAttacherWithNegation(negatePlan, p));
+ p -> getFilterAttacherWithNegation(negatePlan, p, connectionsGroup));
} else {
PlanNode invalidValuesDirectOnPath = path.get()
.getAnyAdded(connectionsGroup, validationSettings.getDataGraph(),
- planNode -> getFilterAttacherWithNegation(negatePlan, planNode));
+ planNode -> getFilterAttacherWithNegation(negatePlan, planNode, connectionsGroup));
PlanNode addedTargets = effectiveTarget.getPlanNode(connectionsGroup, validationSettings.getDataGraph(),
scope, false, null);
- InnerJoin innerJoin = new InnerJoin(addedTargets, invalidValuesDirectOnPath);
+ InnerJoin innerJoin = new InnerJoin(addedTargets, invalidValuesDirectOnPath, connectionsGroup);
if (connectionsGroup.getStats().wasEmptyBeforeTransaction()) {
return innerJoin.getJoined(UnBufferedPlanNode.class);
@@ -120,7 +119,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
scope,
EffectiveTarget.Extend.left, true, null);
- top = UnionNode.getInstance(top, typeFilterPlan);
+ top = UnionNode.getInstance(connectionsGroup, top, typeFilterPlan);
PlanNode bulkedExternalInnerJoin = new BulkedExternalInnerJoin(
effectiveTarget.getPlanNode(connectionsGroup, validationSettings.getDataGraph(), scope, false,
@@ -128,18 +127,19 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getBaseConnection(),
validationSettings.getDataGraph(),
path.get()
- .getTargetQueryFragment(new StatementMatcher.Variable("a"),
- new StatementMatcher.Variable("c"),
+ .getTargetQueryFragment(new Variable("a"),
+ new Variable("c"),
connectionsGroup.getRdfsSubClassOfReasoner(),
stableRandomVariableProvider, Set.of()),
connectionsGroup.hasPreviousStateConnection(),
connectionsGroup.getPreviousStateConnection(),
b -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph()));
+ validationSettings.getDataGraph()),
+ connectionsGroup);
- top = UnionNode.getInstance(top, bulkedExternalInnerJoin);
+ top = UnionNode.getInstance(connectionsGroup, top, bulkedExternalInnerJoin);
- return getFilterAttacherWithNegation(negatePlan, top);
+ return getFilterAttacherWithNegation(negatePlan, top, connectionsGroup);
}
}
@@ -157,17 +157,26 @@ private PlanNode getPlanNodeForOverrideTargetNode(ConnectionsGroup connectionsGr
if (overrideTargetPlanNode instanceof AllTargetsPlanNode) {
PlanNode allTargets = effectiveTarget.getAllTargets(connectionsGroup,
validationSettings.getDataGraph(), scope);
- allTargets = getFilterAttacherWithNegation(negatePlan, allTargets);
+ allTargets = getFilterAttacherWithNegation(negatePlan, allTargets, connectionsGroup);
- return Unique.getInstance(allTargets, true);
+ if (effectiveTarget.size() > 1) {
+ allTargets = Unique.getInstance(allTargets, true, connectionsGroup);
+ }
+ return allTargets;
} else {
- return effectiveTarget.extend(overrideTargetPlanNode, connectionsGroup,
+ PlanNode extend = effectiveTarget.extend(overrideTargetPlanNode, connectionsGroup,
validationSettings.getDataGraph(), scope,
EffectiveTarget.Extend.right,
false,
- p -> getFilterAttacherWithNegation(negatePlan, p)
+ p -> getFilterAttacherWithNegation(negatePlan, p, connectionsGroup)
);
+ if (effectiveTarget.size() > 1) {
+ extend = Unique.getInstance(extend, true, connectionsGroup);
+ }
+
+ return extend;
+
}
} else {
@@ -180,11 +189,15 @@ private PlanNode getPlanNodeForOverrideTargetNode(ConnectionsGroup connectionsGr
.getEffectiveTarget(Scope.nodeShape,
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider)
.getAllTargets(connectionsGroup, validationSettings.getDataGraph(), Scope.nodeShape);
- allTargets = new ShiftToPropertyShape(allTargets);
+ allTargets = new ShiftToPropertyShape(allTargets, connectionsGroup);
+
+ allTargets = getFilterAttacherWithNegation(negatePlan, allTargets, connectionsGroup);
- allTargets = getFilterAttacherWithNegation(negatePlan, allTargets);
+ if (effectiveTarget.size() > 1) {
+ allTargets = Unique.getInstance(allTargets, true, connectionsGroup);
+ }
- return Unique.getInstance(allTargets, true);
+ return allTargets;
} else {
@@ -192,21 +205,25 @@ private PlanNode getPlanNodeForOverrideTargetNode(ConnectionsGroup connectionsGr
validationSettings.getDataGraph(), scope,
EffectiveTarget.Extend.right, false, null);
+ if (effectiveTarget.size() > 1) {
+ overrideTargetPlanNode = Unique.getInstance(overrideTargetPlanNode, true, connectionsGroup);
+ }
+
planNode = new BulkedExternalInnerJoin(overrideTargetPlanNode,
connectionsGroup.getBaseConnection(),
validationSettings.getDataGraph(), path.get()
- .getTargetQueryFragment(new StatementMatcher.Variable("a"),
- new StatementMatcher.Variable("c"),
+ .getTargetQueryFragment(new Variable("a"),
+ new Variable("c"),
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider,
Set.of()),
false, null,
- BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph())
- );
+ BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
+ connectionsGroup);
planNode = connectionsGroup.getCachedNodeFor(planNode);
}
}
- return getFilterAttacherWithNegation(negatePlan, planNode);
+ return getFilterAttacherWithNegation(negatePlan, planNode, connectionsGroup);
}
@Override
@@ -228,7 +245,7 @@ public ValidationQuery generateSparqlValidationQuery(ConnectionsGroup connection
query += "\n" + getSparqlFilter(negatePlan, effectiveTarget.getTargetVar(), stableRandomVariableProvider);
} else {
- value = StatementMatcher.Variable.VALUE;
+ value = Variable.VALUE;
Optional sparqlFragment = targetChain.getPath()
.map(p -> p.getTargetQueryFragment(effectiveTarget.getTargetVar(), value,
@@ -273,11 +290,12 @@ private String getSparqlFilter(boolean negatePlan, Variable variable,
*/
abstract String getSparqlFilterExpression(Variable variable, boolean negated);
- private PlanNode getFilterAttacherWithNegation(boolean negatePlan, PlanNode allTargets) {
+ private PlanNode getFilterAttacherWithNegation(boolean negatePlan, PlanNode allTargets,
+ ConnectionsGroup connectionsGroup) {
if (negatePlan) {
- allTargets = getFilterAttacher().apply(allTargets).getTrueNode(UnBufferedPlanNode.class);
+ allTargets = getFilterAttacher(connectionsGroup).apply(allTargets).getTrueNode(UnBufferedPlanNode.class);
} else {
- allTargets = getFilterAttacher().apply(allTargets).getFalseNode(UnBufferedPlanNode.class);
+ allTargets = getFilterAttacher(connectionsGroup).apply(allTargets).getFalseNode(UnBufferedPlanNode.class);
}
return allTargets;
}
@@ -297,7 +315,7 @@ public SourceConstraintComponent getConstraintComponent() {
throw new ShaclUnsupportedException(this.getClass().getSimpleName());
}
- abstract Function getFilterAttacher();
+ abstract Function getFilterAttacher(ConnectionsGroup connectionsGroup);
String literalToString(Literal literal) {
IRI datatype = (literal).getDatatype();
@@ -314,13 +332,26 @@ String literalToString(Literal literal) {
@Override
public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[] dataGraph, Scope scope,
StatementMatcher.StableRandomVariableProvider stableRandomVariableProvider) {
+
if (scope == Scope.propertyShape) {
- PlanNode allTargetsPlan = getTargetChain()
- .getEffectiveTarget(Scope.nodeShape, connectionsGroup.getRdfsSubClassOfReasoner(),
- stableRandomVariableProvider)
- .getPlanNode(connectionsGroup, dataGraph, Scope.nodeShape, true, null);
- return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan), true);
+ EffectiveTarget effectiveTarget = getTargetChain()
+ .getEffectiveTarget(
+ Scope.nodeShape,
+ connectionsGroup.getRdfsSubClassOfReasoner(),
+ stableRandomVariableProvider
+ );
+
+ PlanNode allTargetsPlan = effectiveTarget
+ .getPlanNode(
+ connectionsGroup,
+ dataGraph, Scope.nodeShape,
+ true,
+ null
+ );
+
+ return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup),
+ effectiveTarget.size() > 1, connectionsGroup);
}
return EmptyNode.getInstance();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AndConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AndConstraintComponent.java
index ddaef28934e..aa6bb4f8860 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AndConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AndConstraintComponent.java
@@ -112,10 +112,10 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode planNode = and.stream()
.map(a -> a.generateTransactionalValidationPlan(connectionsGroup, validationSettings,
overrideTargetNode, scope))
- .reduce(UnionNode::getInstance)
+ .reduce((nodes, nodes2) -> UnionNode.getInstance(connectionsGroup, nodes, nodes2))
.orElse(EmptyNode.getInstance());
- return Unique.getInstance(planNode, false);
+ return Unique.getInstance(planNode, false, connectionsGroup);
}
@@ -126,10 +126,10 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
.map(c -> c.getAllTargetsPlan(connectionsGroup, dataGraph, scope,
new StatementMatcher.StableRandomVariableProvider()))
.distinct()
- .reduce(UnionNode::getInstanceDedupe)
+ .reduce((nodes, nodes2) -> UnionNode.getInstanceDedupe(connectionsGroup, nodes, nodes2))
.orElse(EmptyNode.getInstance());
- planNode = Unique.getInstance(planNode, false);
+ planNode = Unique.getInstance(planNode, false, connectionsGroup);
return planNode;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClassConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClassConstraintComponent.java
index 94ea3e2be3c..8dde6295aff 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClassConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClassConstraintComponent.java
@@ -29,6 +29,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.ValidationApproach;
import org.eclipse.rdf4j.sail.shacl.ast.ValidationQuery;
import org.eclipse.rdf4j.sail.shacl.ast.paths.Path;
+import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AllTargetsPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BufferedSplitter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalInnerJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EmptyNode;
@@ -85,22 +86,44 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode addedTargets;
if (overrideTargetNode != null) {
- addedTargets = effectiveTarget.extend(overrideTargetNode.getPlanNode(), connectionsGroup,
- validationSettings.getDataGraph(), scope,
- EffectiveTarget.Extend.right,
- false, null);
+ PlanNode planNode = overrideTargetNode.getPlanNode();
+ if (planNode instanceof AllTargetsPlanNode) {
+ // We are cheating a bit here by retrieving all the targets and values at the same time by
+ // pretending to be in node shape scope and then shifting the results back to property shape scope
+ PlanNode allTargets = getTargetChain()
+ .getEffectiveTarget(Scope.nodeShape,
+ connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider)
+ .getAllTargets(connectionsGroup, validationSettings.getDataGraph(), Scope.nodeShape);
+ allTargets = new ShiftToPropertyShape(allTargets, connectionsGroup);
+
+ // filter by type against the base sail
+ allTargets = new FilterByPredicateObject(
+ connectionsGroup.getBaseConnection(),
+ validationSettings.getDataGraph(), RDF.TYPE, clazzSet,
+ allTargets, false, FilterByPredicateObject.FilterOn.value, true, connectionsGroup);
+
+ return allTargets;
+
+ } else {
+ addedTargets = effectiveTarget.extend(planNode, connectionsGroup,
+ validationSettings.getDataGraph(), scope,
+ EffectiveTarget.Extend.right,
+ false, null);
+ }
} else {
- BufferedSplitter addedTargetsBufferedSplitter = new BufferedSplitter(
+ BufferedSplitter addedTargetsBufferedSplitter = BufferedSplitter.getInstance(
effectiveTarget.getPlanNode(connectionsGroup, validationSettings.getDataGraph(), scope, false,
null));
addedTargets = addedTargetsBufferedSplitter.getPlanNode();
PlanNode addedByPath = path.getAllAdded(connectionsGroup, validationSettings.getDataGraph(), null);
addedByPath = effectiveTarget.getTargetFilter(connectionsGroup,
- validationSettings.getDataGraph(), Unique.getInstance(new TrimToTarget(addedByPath), false));
+ validationSettings.getDataGraph(),
+ Unique.getInstance(new TrimToTarget(addedByPath, connectionsGroup), true, connectionsGroup));
- addedByPath = new ReduceTargets(addedByPath, addedTargetsBufferedSplitter.getPlanNode());
+ addedByPath = new ReduceTargets(addedByPath, addedTargetsBufferedSplitter.getPlanNode(),
+ connectionsGroup);
addedByPath = effectiveTarget.extend(addedByPath, connectionsGroup, validationSettings.getDataGraph(),
scope,
@@ -124,12 +147,19 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider)
.getTargetFilter(connectionsGroup, validationSettings.getDataGraph(), deletedTypes);
- addedTargets = UnionNode.getInstance(addedTargets,
- new TrimToTarget(new ShiftToPropertyShape(deletedTypes)));
+ addedTargets = UnionNode.getInstance(connectionsGroup, addedTargets,
+ new TrimToTarget(new ShiftToPropertyShape(deletedTypes, connectionsGroup),
+ connectionsGroup));
}
- addedTargets = UnionNode.getInstance(addedByPath, addedTargets);
- addedTargets = Unique.getInstance(addedTargets, false);
+ addedTargets = UnionNode.getInstance(connectionsGroup, addedByPath, addedTargets);
+ addedTargets = Unique.getInstance(addedTargets, false, connectionsGroup);
+ }
+
+ int size = effectiveTarget.size();
+
+ if (size > 1) {
+ addedTargets = Unique.getInstance(addedTargets, true, connectionsGroup);
}
PlanNode falseNode = new BulkedExternalInnerJoin(
@@ -140,22 +170,22 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
false,
null,
- BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph())
- );
+ BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
+ connectionsGroup);
if (connectionsGroup.getAddedStatements() != null) {
// filter by type against the added statements
falseNode = new FilterByPredicateObject(
connectionsGroup.getAddedStatements(),
validationSettings.getDataGraph(), RDF.TYPE, clazzSet,
- falseNode, false, FilterByPredicateObject.FilterOn.value, false);
+ falseNode, false, FilterByPredicateObject.FilterOn.value, false, connectionsGroup);
}
// filter by type against the base sail
falseNode = new FilterByPredicateObject(
connectionsGroup.getBaseConnection(),
validationSettings.getDataGraph(), RDF.TYPE, clazzSet,
- falseNode, false, FilterByPredicateObject.FilterOn.value, true);
+ falseNode, false, FilterByPredicateObject.FilterOn.value, true, connectionsGroup);
return falseNode;
@@ -186,7 +216,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
stableRandomVariableProvider)
.extend(deletedTypes, connectionsGroup, validationSettings.getDataGraph(), scope,
EffectiveTarget.Extend.left, false, null);
- addedTargets = UnionNode.getInstance(addedTargets, deletedTypes);
+ addedTargets = UnionNode.getInstance(connectionsGroup, addedTargets, deletedTypes);
}
}
@@ -194,7 +224,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode falseNode = new FilterByPredicateObject(
connectionsGroup.getBaseConnection(),
validationSettings.getDataGraph(), RDF.TYPE, clazzSet,
- addedTargets, false, FilterByPredicateObject.FilterOn.value, true);
+ addedTargets, false, FilterByPredicateObject.FilterOn.value, true, connectionsGroup);
return falseNode;
@@ -228,7 +258,7 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
.extend(deletedTypes, connectionsGroup, dataGraph, Scope.nodeShape, EffectiveTarget.Extend.left,
false,
null);
- allTargetsPlan = UnionNode.getInstanceDedupe(allTargetsPlan, deletedTypes);
+ allTargetsPlan = UnionNode.getInstanceDedupe(connectionsGroup, allTargetsPlan, deletedTypes);
}
// added type statements that match clazz could affect sh:not
@@ -246,10 +276,12 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
.extend(addedTypes, connectionsGroup, dataGraph, Scope.nodeShape, EffectiveTarget.Extend.left,
false,
null);
- allTargetsPlan = UnionNode.getInstanceDedupe(allTargetsPlan, addedTypes);
+ allTargetsPlan = UnionNode.getInstanceDedupe(connectionsGroup, allTargetsPlan, addedTypes);
}
- return Unique.getInstance(new TrimToTarget(new ShiftToPropertyShape(allTargetsPlan)), false);
+ return Unique.getInstance(
+ new TrimToTarget(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup), connectionsGroup),
+ false, connectionsGroup);
}
PlanNode allTargetsPlan = EmptyNode.getInstance();
@@ -266,7 +298,7 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.extend(deletedTypes, connectionsGroup, dataGraph, Scope.nodeShape, EffectiveTarget.Extend.left,
false, null);
- allTargetsPlan = UnionNode.getInstanceDedupe(allTargetsPlan, deletedTypes);
+ allTargetsPlan = UnionNode.getInstanceDedupe(connectionsGroup, allTargetsPlan, deletedTypes);
}
@@ -283,11 +315,11 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.extend(addedTypes, connectionsGroup, dataGraph, Scope.nodeShape, EffectiveTarget.Extend.left,
false, null);
- allTargetsPlan = UnionNode.getInstanceDedupe(allTargetsPlan, addedTypes);
+ allTargetsPlan = UnionNode.getInstanceDedupe(connectionsGroup, allTargetsPlan, addedTypes);
}
- return Unique.getInstance(allTargetsPlan, false);
+ return Unique.getInstance(allTargetsPlan, false, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClosedConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClosedConstraintComponent.java
index ac4fa3f2e4a..64bf3dcc2f0 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClosedConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClosedConstraintComponent.java
@@ -139,16 +139,18 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
false, null);
} else {
- BufferedSplitter addedTargetsBufferedSplitter = new BufferedSplitter(
+ BufferedSplitter addedTargetsBufferedSplitter = BufferedSplitter.getInstance(
effectiveTarget.getPlanNode(connectionsGroup, validationSettings.getDataGraph(), scope, false,
null));
addedTargets = addedTargetsBufferedSplitter.getPlanNode();
PlanNode addedByPath = path.getAllAdded(connectionsGroup, validationSettings.getDataGraph(), null);
addedByPath = effectiveTarget.getTargetFilter(connectionsGroup,
- validationSettings.getDataGraph(), Unique.getInstance(new TrimToTarget(addedByPath), false));
+ validationSettings.getDataGraph(),
+ Unique.getInstance(new TrimToTarget(addedByPath, connectionsGroup), false, connectionsGroup));
- addedByPath = new ReduceTargets(addedByPath, addedTargetsBufferedSplitter.getPlanNode());
+ addedByPath = new ReduceTargets(addedByPath, addedTargetsBufferedSplitter.getPlanNode(),
+ connectionsGroup);
addedByPath = effectiveTarget.extend(addedByPath, connectionsGroup, validationSettings.getDataGraph(),
scope,
@@ -173,11 +175,11 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider)
.getTargetFilter(connectionsGroup, validationSettings.getDataGraph(), addedByValue);
- addedTargets = UnionNode.getInstance(addedTargets,
- new TrimToTarget(new ShiftToPropertyShape(addedByValue)));
+ addedTargets = UnionNode.getInstance(connectionsGroup, addedTargets,
+ new TrimToTarget(new ShiftToPropertyShape(addedByValue, connectionsGroup), connectionsGroup));
- addedTargets = UnionNode.getInstance(addedByPath, addedTargets);
- addedTargets = Unique.getInstance(addedTargets, false);
+ addedTargets = UnionNode.getInstance(connectionsGroup, addedByPath, addedTargets);
+ addedTargets = Unique.getInstance(addedTargets, false, connectionsGroup);
}
@@ -189,8 +191,8 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
false,
null,
- BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph())
- );
+ BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
+ connectionsGroup);
StatementMatcher.Variable subjectVariable = stableRandomVariableProvider.next();
StatementMatcher.Variable predicateVariable = stableRandomVariableProvider.next();
@@ -229,7 +231,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
return validationTuple;
- })
+ }, connectionsGroup)
.getTrueNode(UnBufferedPlanNode.class);
return falseNode1;
@@ -258,10 +260,10 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
}));
// then remove any that are in the addedTargets node
- PlanNode notValuesIn = new ReduceTargets(unorderedSelect, addedTargets);
+ PlanNode notValuesIn = new ReduceTargets(unorderedSelect, addedTargets, connectionsGroup);
// remove duplicates
- PlanNode unique = Unique.getInstance(notValuesIn, false);
+ PlanNode unique = Unique.getInstance(notValuesIn, false, connectionsGroup);
// then check that the rest are actually targets
PlanNode targetFilter = effectiveTarget.getTargetFilter(connectionsGroup,
@@ -273,8 +275,9 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
validationSettings.getDataGraph(),
scope, EffectiveTarget.Extend.left, false, null);
- targetNodePlanNode = UnionNode.getInstance(extend, effectiveTarget.getPlanNode(connectionsGroup,
- validationSettings.getDataGraph(), scope, false, null));
+ targetNodePlanNode = UnionNode.getInstance(connectionsGroup, extend,
+ effectiveTarget.getPlanNode(connectionsGroup,
+ validationSettings.getDataGraph(), scope, false, null));
}
StatementMatcher.Variable predicateVariable = stableRandomVariableProvider.next();
@@ -288,7 +291,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
SparqlFragment sparqlFragment = SparqlFragment.join(List.of(bgp, sparqlFragmentFilter));
BulkedExternalInnerJoin bulkedExternalInnerJoin = new BulkedExternalInnerJoin(
- Unique.getInstance(targetNodePlanNode, false),
+ Unique.getInstance(targetNodePlanNode, false, connectionsGroup),
connectionsGroup.getBaseConnection(),
validationSettings.getDataGraph(),
sparqlFragment,
@@ -313,8 +316,8 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
});
}
return validationTuple;
- }
- );
+ },
+ connectionsGroup);
return bulkedExternalInnerJoin;
}
@@ -333,7 +336,7 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
throw new IllegalStateException();
case nodeShape:
- BufferedSplitter targets = new BufferedSplitter(
+ BufferedSplitter targets = BufferedSplitter.getInstance(
effectiveTarget.getPlanNode(connectionsGroup, dataGraph, scope, false,
null));
// get all subjects of all triples where the predicate is not in the allAllowedPredicates set
@@ -345,7 +348,7 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
// then remove any that are in the targets node
statementsNotMatchingPredicateList = new ReduceTargets(statementsNotMatchingPredicateList,
- targets.getPlanNode());
+ targets.getPlanNode(), connectionsGroup);
// then check that the rest are actually targets
statementsNotMatchingPredicateList = effectiveTarget.getTargetFilter(connectionsGroup,
@@ -360,17 +363,18 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
UnorderedSelect.Mapper.SubjectScopedMapper.getFunction(scope),
(statement -> !allAllowedPredicates.contains(statement.getPredicate())));
- removed = new ReduceTargets(removed, targets.getPlanNode());
+ removed = new ReduceTargets(removed, targets.getPlanNode(), connectionsGroup);
// then check that the rest are actually targets
removed = effectiveTarget.getTargetFilter(connectionsGroup, dataGraph, removed);
- statementsNotMatchingPredicateList = UnionNode.getInstance(statementsNotMatchingPredicateList, removed);
+ statementsNotMatchingPredicateList = UnionNode.getInstance(connectionsGroup,
+ statementsNotMatchingPredicateList, removed);
}
// union and remove duplicates
- PlanNode unique = Unique.getInstance(statementsNotMatchingPredicateList, false);
+ PlanNode unique = Unique.getInstance(statementsNotMatchingPredicateList, false, connectionsGroup);
// this should now be targets that are not valid
PlanNode extend = effectiveTarget.extend(unique, connectionsGroup,
@@ -382,16 +386,17 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
case propertyShape:
Path path = getTargetChain().getPath().get();
- BufferedSplitter addedTargetsBufferedSplitter = new BufferedSplitter(
+ BufferedSplitter addedTargetsBufferedSplitter = BufferedSplitter.getInstance(
effectiveTarget.getPlanNode(connectionsGroup, dataGraph, scope, false,
null));
PlanNode addedTargets = addedTargetsBufferedSplitter.getPlanNode();
PlanNode addedByPath = path.getAllAdded(connectionsGroup, dataGraph, null);
addedByPath = effectiveTarget.getTargetFilter(connectionsGroup,
- dataGraph, Unique.getInstance(new TrimToTarget(addedByPath), false));
+ dataGraph,
+ Unique.getInstance(new TrimToTarget(addedByPath, connectionsGroup), false, connectionsGroup));
- addedByPath = new ReduceTargets(addedByPath, addedTargetsBufferedSplitter.getPlanNode());
+ addedByPath = new ReduceTargets(addedByPath, addedTargetsBufferedSplitter.getPlanNode(), connectionsGroup);
addedByPath = effectiveTarget.extend(addedByPath, connectionsGroup, dataGraph,
scope,
@@ -410,7 +415,7 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
return !allAllowedPredicates.contains(statement.getPredicate());
}));
- addedByValue = UnionNode.getInstance(addedByValue, removedByValue);
+ addedByValue = UnionNode.getInstance(connectionsGroup, addedByValue, removedByValue);
addedByValue = getTargetChain()
.getEffectiveTarget(Scope.nodeShape,
@@ -424,11 +429,11 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider)
.getTargetFilter(connectionsGroup, dataGraph, addedByValue);
- addedTargets = UnionNode.getInstance(addedTargets,
- new TrimToTarget(new ShiftToPropertyShape(addedByValue)));
+ addedTargets = UnionNode.getInstance(connectionsGroup, addedTargets,
+ new TrimToTarget(new ShiftToPropertyShape(addedByValue, connectionsGroup), connectionsGroup));
- addedTargets = UnionNode.getInstance(addedByPath, addedTargets);
- addedTargets = Unique.getInstance(addedTargets, false);
+ addedTargets = UnionNode.getInstance(connectionsGroup, addedByPath, addedTargets);
+ addedTargets = Unique.getInstance(addedTargets, false, connectionsGroup);
return addedTargets;
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DashHasValueInConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DashHasValueInConstraintComponent.java
index 276b2614489..450b0ce4ecd 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DashHasValueInConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DashHasValueInConstraintComponent.java
@@ -112,14 +112,14 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
path.getTargetQueryFragment(new StatementMatcher.Variable("a"), new StatementMatcher.Variable("c"),
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph())
- );
+ validationSettings.getDataGraph()),
+ connectionsGroup);
PlanNode invalidTargets = new GroupByFilter(joined, group -> {
return group.stream().map(ValidationTuple::getValue).noneMatch(hasValueIn::contains);
- });
+ }, connectionsGroup);
- return Unique.getInstance(new TrimToTarget(invalidTargets), false);
+ return Unique.getInstance(new TrimToTarget(invalidTargets, connectionsGroup), false, connectionsGroup);
} else if (scope == Scope.nodeShape) {
@@ -136,7 +136,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
null);
}
- PlanNode falseNode = new ValueInFilter(addedTargets, hasValueIn)
+ PlanNode falseNode = new ValueInFilter(addedTargets, hasValueIn, connectionsGroup)
.getFalseNode(UnBufferedPlanNode.class);
return falseNode;
@@ -156,7 +156,8 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.getPlanNode(connectionsGroup, dataGraph, Scope.nodeShape, true, null);
- return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan), true);
+ return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup), true,
+ connectionsGroup);
}
return EmptyNode.getInstance();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DatatypeConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DatatypeConstraintComponent.java
index 8d6086edaad..b2571243577 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DatatypeConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DatatypeConstraintComponent.java
@@ -28,13 +28,15 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.DatatypeFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class DatatypeConstraintComponent extends SimpleAbstractConstraintComponent {
+public class DatatypeConstraintComponent extends AbstractSimpleConstraintComponent {
private final CoreDatatype coreDatatype;
private final IRI datatype;
public DatatypeConstraintComponent(IRI datatype) {
+ super();
this.datatype = datatype;
this.coreDatatype = CoreDatatype.from(datatype);
}
@@ -55,8 +57,8 @@ public ConstraintComponent deepClone() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new DatatypeFilter(parent, datatype);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new DatatypeFilter(parent, datatype, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java
index d629199c076..7dbfea97a80 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java
@@ -93,12 +93,12 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode addedByPath = path.getAllAdded(connectionsGroup, validationSettings.getDataGraph(), null);
addedByPath = target.getTargetFilter(connectionsGroup, validationSettings.getDataGraph(),
- Unique.getInstance(new TrimToTarget(addedByPath), false));
+ Unique.getInstance(new TrimToTarget(addedByPath, connectionsGroup), false, connectionsGroup));
addedByPath = target.extend(addedByPath, connectionsGroup, validationSettings.getDataGraph(), scope,
EffectiveTarget.Extend.left, false, null);
- addedTargets = UnionNode.getInstance(addedByPath, addedTargets);
- addedTargets = Unique.getInstance(addedTargets, false);
+ addedTargets = UnionNode.getInstance(connectionsGroup, addedByPath, addedTargets);
+ addedTargets = Unique.getInstance(addedTargets, false, connectionsGroup);
}
PlanNode joined = new BulkedExternalLeftOuterJoin(addedTargets, connectionsGroup.getBaseConnection(),
@@ -106,16 +106,17 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
path.getTargetQueryFragment(new Variable<>("a"), new Variable<>("c"),
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph()));
+ validationSettings.getDataGraph()),
+ connectionsGroup);
PlanNode invalidTargets = new GroupByFilter(joined, group -> {
return group
.stream()
.map(ValidationTuple::getValue)
.noneMatch(v -> hasValue.equals(v));
- });
+ }, connectionsGroup);
- return Unique.getInstance(new TrimToTarget(invalidTargets), false);
+ return Unique.getInstance(new TrimToTarget(invalidTargets, connectionsGroup), false, connectionsGroup);
} else if (scope == Scope.nodeShape) {
@@ -129,7 +130,8 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
null);
}
- PlanNode falseNode = new ValueInFilter(addedTargets, new HashSet<>(Collections.singletonList(hasValue)))
+ PlanNode falseNode = new ValueInFilter(addedTargets, new HashSet<>(Collections.singletonList(hasValue)),
+ connectionsGroup)
.getFalseNode(UnBufferedPlanNode.class);
return falseNode;
@@ -149,7 +151,8 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.getPlanNode(connectionsGroup, dataGraph, Scope.nodeShape, true, null);
- return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan), true);
+ return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup), true,
+ connectionsGroup);
}
return EmptyNode.getInstance();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/InConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/InConstraintComponent.java
index 0b55203f2dc..df2b549f8ad 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/InConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/InConstraintComponent.java
@@ -29,9 +29,10 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.ValueInFilter;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.eclipse.rdf4j.sail.shacl.wrapper.shape.ShapeSource;
-public class InConstraintComponent extends SimpleAbstractConstraintComponent {
+public class InConstraintComponent extends AbstractSimpleConstraintComponent {
private final Set in;
@@ -98,8 +99,8 @@ private String getInSetAsString() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new ValueInFilter(parent, in);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new ValueInFilter(parent, in, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/LanguageInConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/LanguageInConstraintComponent.java
index 09e4b404844..a6542ae19aa 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/LanguageInConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/LanguageInConstraintComponent.java
@@ -32,9 +32,10 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.LanguageInFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.eclipse.rdf4j.sail.shacl.wrapper.shape.ShapeSource;
-public class LanguageInConstraintComponent extends SimpleAbstractConstraintComponent {
+public class LanguageInConstraintComponent extends AbstractSimpleConstraintComponent {
private final List languageIn;
private final ArrayList languageRanges;
@@ -103,8 +104,8 @@ public ConstraintComponent deepClone() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new LanguageInFilter(parent, lowerCaseLanguageIn, languageRanges);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new LanguageInFilter(parent, lowerCaseLanguageIn, languageRanges, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxCountConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxCountConstraintComponent.java
index 6adefc57fee..b9564ba2e35 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxCountConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxCountConstraintComponent.java
@@ -44,9 +44,20 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.ValidationTuple;
import org.eclipse.rdf4j.sail.shacl.ast.targets.EffectiveTarget;
import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class MaxCountConstraintComponent extends AbstractConstraintComponent {
+ private static final Logger logger = LoggerFactory.getLogger(MaxCountConstraintComponent.class);
+
+ // Performance degrades quickly as the maxCount increases when using a SPARQL Validation Approach. The default is 5,
+ // but it can be tuned using the system property below.
+ private static final String SPARQL_VALIDATION_APPROACH_LIMIT_PROPERTY = "org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.MaxCountConstraintComponent.sparqlValidationApproachLimit";
+ public static long SPARQL_VALIDATION_APPROACH_LIMIT = System
+ .getProperty(SPARQL_VALIDATION_APPROACH_LIMIT_PROPERTY) == null ? 1
+ : Long.parseLong(System.getProperty(SPARQL_VALIDATION_APPROACH_LIMIT_PROPERTY));
+
private final long maxCount;
public MaxCountConstraintComponent(long maxCount) {
@@ -85,7 +96,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
effectiveTarget, path.get(), false);
}
- mergeNode = Unique.getInstance(new TrimToTarget(mergeNode), false);
+ mergeNode = Unique.getInstance(new TrimToTarget(mergeNode, connectionsGroup), false, connectionsGroup);
PlanNode relevantTargetsWithPath;
@@ -101,8 +112,8 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
Set.of()),
false,
null,
- BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph())
- );
+ BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
+ connectionsGroup);
} else {
relevantTargetsWithPath = new BulkedExternalLeftOuterJoin(
mergeNode,
@@ -114,15 +125,16 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider,
Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph())
- );
+ validationSettings.getDataGraph()),
+ connectionsGroup);
}
relevantTargetsWithPath = connectionsGroup.getCachedNodeFor(relevantTargetsWithPath);
- PlanNode groupByCount = new GroupByCountFilter(relevantTargetsWithPath, count -> count > maxCount);
+ PlanNode groupByCount = new GroupByCountFilter(relevantTargetsWithPath, count -> count > maxCount,
+ connectionsGroup);
- return Unique.getInstance(new TrimToTarget(groupByCount), false);
+ return Unique.getInstance(new TrimToTarget(groupByCount, connectionsGroup), false, connectionsGroup);
}
@@ -135,7 +147,8 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.getPlanNode(connectionsGroup, dataGraph, Scope.nodeShape, true, null);
- return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan), true);
+ return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup), true,
+ connectionsGroup);
}
return EmptyNode.getInstance();
}
@@ -216,8 +229,12 @@ public ValidationQuery generateSparqlValidationQuery(ConnectionsGroup connection
@Override
public ValidationApproach getOptimalBulkValidationApproach() {
- // performance of large maxCount is terrible
- if (maxCount > 5) {
+ if (maxCount > SPARQL_VALIDATION_APPROACH_LIMIT) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "maxCount is {}, which is greater than the limit of {}, using ValidationApproach.Transactional instead of ValidationApproach.SPARQL for {}",
+ maxCount, SPARQL_VALIDATION_APPROACH_LIMIT, stringRepresentationOfValue(getId()));
+ }
return ValidationApproach.Transactional;
}
return ValidationApproach.SPARQL;
@@ -244,6 +261,6 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
- return (int) (maxCount ^ (maxCount >>> 32)) + "MaxCountConstraintComponent".hashCode();
+ return Long.hashCode(maxCount) + "MaxCountConstraintComponent".hashCode();
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxExclusiveConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxExclusiveConstraintComponent.java
index 0fb7d81e6af..8f1ef0cd175 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxExclusiveConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxExclusiveConstraintComponent.java
@@ -27,12 +27,14 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.LiteralComparatorFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class MaxExclusiveConstraintComponent extends SimpleAbstractConstraintComponent {
+public class MaxExclusiveConstraintComponent extends AbstractSimpleConstraintComponent {
Literal maxExclusive;
public MaxExclusiveConstraintComponent(Literal maxExclusive) {
+ super();
this.maxExclusive = maxExclusive;
}
@@ -61,8 +63,8 @@ public ConstraintComponent deepClone() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new LiteralComparatorFilter(parent, maxExclusive, Compare.CompareOp.GT);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new LiteralComparatorFilter(parent, maxExclusive, Compare.CompareOp.GT, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxInclusiveConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxInclusiveConstraintComponent.java
index 864e9c2b321..2713f231748 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxInclusiveConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxInclusiveConstraintComponent.java
@@ -27,12 +27,14 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.LiteralComparatorFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class MaxInclusiveConstraintComponent extends SimpleAbstractConstraintComponent {
+public class MaxInclusiveConstraintComponent extends AbstractSimpleConstraintComponent {
Literal maxInclusive;
public MaxInclusiveConstraintComponent(Literal maxInclusive) {
+ super();
this.maxInclusive = maxInclusive;
}
@@ -61,8 +63,8 @@ public ConstraintComponent deepClone() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new LiteralComparatorFilter(parent, maxInclusive, Compare.CompareOp.GE);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new LiteralComparatorFilter(parent, maxInclusive, Compare.CompareOp.GE, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxLengthConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxLengthConstraintComponent.java
index a24d9d312bc..63f3cd979d6 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxLengthConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxLengthConstraintComponent.java
@@ -29,12 +29,14 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.MaxLengthFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class MaxLengthConstraintComponent extends SimpleAbstractConstraintComponent {
+public class MaxLengthConstraintComponent extends AbstractSimpleConstraintComponent {
long maxLength;
public MaxLengthConstraintComponent(long maxLength) {
+ super();
this.maxLength = maxLength;
}
@@ -54,8 +56,8 @@ String getSparqlFilterExpression(Variable variable, boolean negated) {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new MaxLengthFilter(parent, maxLength);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new MaxLengthFilter(parent, maxLength, connectionsGroup);
}
@Override
@@ -89,6 +91,6 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
- return (int) (maxLength ^ (maxLength >>> 32)) + "MaxLengthConstraintComponent".hashCode();
+ return Long.hashCode(maxLength) + "MaxLengthConstraintComponent".hashCode();
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinCountConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinCountConstraintComponent.java
index 7d67d7fc855..19ebb4c0787 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinCountConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinCountConstraintComponent.java
@@ -82,8 +82,8 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode addedByPath = getTargetChain().getPath()
.get()
.getAnyAdded(connectionsGroup, validationSettings.getDataGraph(), null);
- LeftOuterJoin leftOuterJoin = new LeftOuterJoin(target, addedByPath);
- target = new GroupByCountFilter(leftOuterJoin, count -> count < minCount);
+ LeftOuterJoin leftOuterJoin = new LeftOuterJoin(target, addedByPath, connectionsGroup);
+ target = new GroupByCountFilter(leftOuterJoin, count -> count < minCount, connectionsGroup);
}
} else {
// we can assume that we are not doing bulk validation, so it is worth checking our added statements before
@@ -97,26 +97,27 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode addedByPath = getTargetChain().getPath()
.get()
.getAnyAdded(connectionsGroup, validationSettings.getDataGraph(), null);
- LeftOuterJoin leftOuterJoin = new LeftOuterJoin(target, addedByPath);
- target = new GroupByCountFilter(leftOuterJoin, count -> count < minCount);
+ LeftOuterJoin leftOuterJoin = new LeftOuterJoin(target, addedByPath, connectionsGroup);
+ target = new GroupByCountFilter(leftOuterJoin, count -> count < minCount, connectionsGroup);
}
PlanNode relevantTargetsWithPath = new BulkedExternalLeftOuterJoin(
- Unique.getInstance(new TrimToTarget(target), false),
+ Unique.getInstance(new TrimToTarget(target, connectionsGroup), false, connectionsGroup),
connectionsGroup.getBaseConnection(),
validationSettings.getDataGraph(), getTargetChain().getPath()
.get()
.getTargetQueryFragment(new StatementMatcher.Variable("a"), new StatementMatcher.Variable("c"),
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph())
- );
+ validationSettings.getDataGraph()),
+ connectionsGroup);
relevantTargetsWithPath = connectionsGroup.getCachedNodeFor(relevantTargetsWithPath);
- PlanNode groupByCount = new GroupByCountFilter(relevantTargetsWithPath, count -> count < minCount);
+ PlanNode groupByCount = new GroupByCountFilter(relevantTargetsWithPath, count -> count < minCount,
+ connectionsGroup);
- return Unique.getInstance(new TrimToTarget(groupByCount), false);
+ return Unique.getInstance(new TrimToTarget(groupByCount, connectionsGroup), false, connectionsGroup);
}
@@ -227,6 +228,6 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
- return (int) (minCount ^ (minCount >>> 32)) + "MinCountConstraintComponent".hashCode();
+ return Long.hashCode(minCount) + "MinCountConstraintComponent".hashCode();
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinExclusiveConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinExclusiveConstraintComponent.java
index cd32c0e50ef..b8448811711 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinExclusiveConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinExclusiveConstraintComponent.java
@@ -27,12 +27,14 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.LiteralComparatorFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class MinExclusiveConstraintComponent extends SimpleAbstractConstraintComponent {
+public class MinExclusiveConstraintComponent extends AbstractSimpleConstraintComponent {
Literal minExclusive;
public MinExclusiveConstraintComponent(Literal minExclusive) {
+ super();
this.minExclusive = minExclusive;
}
@@ -61,8 +63,8 @@ public ConstraintComponent deepClone() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new LiteralComparatorFilter(parent, minExclusive, Compare.CompareOp.LT);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new LiteralComparatorFilter(parent, minExclusive, Compare.CompareOp.LT, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinInclusiveConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinInclusiveConstraintComponent.java
index e366d90a7a4..d9654cc37b8 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinInclusiveConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinInclusiveConstraintComponent.java
@@ -27,12 +27,14 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.LiteralComparatorFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class MinInclusiveConstraintComponent extends SimpleAbstractConstraintComponent {
+public class MinInclusiveConstraintComponent extends AbstractSimpleConstraintComponent {
Literal minInclusive;
public MinInclusiveConstraintComponent(Literal minInclusive) {
+ super();
this.minInclusive = minInclusive;
}
@@ -61,8 +63,8 @@ public ConstraintComponent deepClone() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new LiteralComparatorFilter(parent, minInclusive, Compare.CompareOp.LE);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new LiteralComparatorFilter(parent, minInclusive, Compare.CompareOp.LE, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinLengthConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinLengthConstraintComponent.java
index 47e9ec119a0..792cb8aaf45 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinLengthConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MinLengthConstraintComponent.java
@@ -29,12 +29,14 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.MinLengthFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class MinLengthConstraintComponent extends SimpleAbstractConstraintComponent {
+public class MinLengthConstraintComponent extends AbstractSimpleConstraintComponent {
long minLength;
public MinLengthConstraintComponent(long minLength) {
+ super();
this.minLength = minLength;
}
@@ -54,8 +56,8 @@ String getSparqlFilterExpression(Variable variable, boolean negated) {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new MinLengthFilter(parent, minLength);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new MinLengthFilter(parent, minLength, connectionsGroup);
}
@Override
@@ -89,6 +91,6 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
- return (int) (minLength ^ (minLength >>> 32)) + "MinLengthConstraintComponent".hashCode();
+ return Long.hashCode(minLength) + "MinLengthConstraintComponent".hashCode();
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/NodeKindConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/NodeKindConstraintComponent.java
index d52274e7a20..e165851bb5b 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/NodeKindConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/NodeKindConstraintComponent.java
@@ -26,12 +26,14 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.NodeKindFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class NodeKindConstraintComponent extends SimpleAbstractConstraintComponent {
+public class NodeKindConstraintComponent extends AbstractSimpleConstraintComponent {
NodeKind nodeKind;
public NodeKindConstraintComponent(Resource nodeKind) {
+ super();
this.nodeKind = NodeKind.from(nodeKind);
}
@@ -74,8 +76,8 @@ public ConstraintComponent deepClone() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new NodeKindFilter(parent, nodeKind);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new NodeKindFilter(parent, nodeKind, connectionsGroup);
}
public enum NodeKind {
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/NotConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/NotConstraintComponent.java
index fe64942deb1..a4d4a208b2d 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/NotConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/NotConstraintComponent.java
@@ -111,7 +111,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
scope
);
- PlanNode invalid = Unique.getInstance(planNode, false);
+ PlanNode invalid = Unique.getInstance(planNode, false, connectionsGroup);
PlanNode allTargetsPlan;
if (overrideTargetNode != null) {
@@ -122,7 +122,8 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
.extend(planNodeProvider.getPlanNode(), connectionsGroup, validationSettings.getDataGraph(),
Scope.nodeShape,
EffectiveTarget.Extend.right, false, null);
- allTargetsPlan = Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan), true);
+ allTargetsPlan = Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup), true,
+ connectionsGroup);
} else {
allTargetsPlan = getTargetChain()
.getEffectiveTarget(scope, connectionsGroup.getRdfsSubClassOfReasoner(),
@@ -136,7 +137,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
allTargetsPlan = planNodeProvider.getPlanNode();
}
- invalid = new NotValuesIn(allTargetsPlan, invalid);
+ invalid = new NotValuesIn(allTargetsPlan, invalid, connectionsGroup);
return invalid;
@@ -174,7 +175,8 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.getPlanNode(connectionsGroup, dataGraph, Scope.nodeShape, true, null);
- allTargets = Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan), true);
+ allTargets = Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup), true,
+ connectionsGroup);
} else {
allTargets = getTargetChain()
.getEffectiveTarget(scope, connectionsGroup.getRdfsSubClassOfReasoner(),
@@ -186,7 +188,8 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
PlanNode notTargets = not.getAllTargetsPlan(connectionsGroup, dataGraph, scope,
new StatementMatcher.StableRandomVariableProvider());
- return Unique.getInstance(UnionNode.getInstanceDedupe(allTargets, notTargets), false);
+ return Unique.getInstance(UnionNode.getInstanceDedupe(connectionsGroup, allTargets, notTargets), false,
+ connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/OrConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/OrConstraintComponent.java
index b5dad58614e..db9c6744675 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/OrConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/OrConstraintComponent.java
@@ -119,7 +119,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
if (overrideTargetNode != null) {
planNodeProvider = overrideTargetNode;
} else {
- planNodeProvider = new BufferedSplitter(
+ planNodeProvider = BufferedSplitter.getInstance(
getAllTargetsPlan(connectionsGroup, validationSettings.getDataGraph(), scope,
stableRandomVariableProvider),
false);
@@ -133,10 +133,10 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
scope
)
)
- .reduce((a, b) -> new EqualsJoinValue(a, b, false))
+ .reduce((a, b) -> new EqualsJoinValue(a, b, false, connectionsGroup))
.orElse(EmptyNode.getInstance());
- return Unique.getInstance(orPlanNodes, false);
+ return Unique.getInstance(orPlanNodes, false, connectionsGroup);
}
@Override
@@ -150,7 +150,8 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.getPlanNode(connectionsGroup, dataGraph, Scope.nodeShape, true, null);
- allTargets = Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan), true);
+ allTargets = Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup), true,
+ connectionsGroup);
} else {
allTargets = getTargetChain()
.getEffectiveTarget(scope, connectionsGroup.getRdfsSubClassOfReasoner(),
@@ -163,10 +164,11 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
.map(or -> or.getAllTargetsPlan(connectionsGroup, dataGraph, scope,
new StatementMatcher.StableRandomVariableProvider()))
.distinct()
- .reduce(UnionNode::getInstanceDedupe)
+ .reduce((nodes, nodes2) -> UnionNode.getInstanceDedupe(connectionsGroup, nodes, nodes2))
.orElse(EmptyNode.getInstance());
- return Unique.getInstance(UnionNode.getInstanceDedupe(allTargets, planNode), false);
+ return Unique.getInstance(UnionNode.getInstanceDedupe(connectionsGroup, allTargets, planNode), false,
+ connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/PatternConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/PatternConstraintComponent.java
index 1cec22276b1..7e1f164a873 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/PatternConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/PatternConstraintComponent.java
@@ -29,13 +29,15 @@
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.FilterPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PatternFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
-public class PatternConstraintComponent extends SimpleAbstractConstraintComponent {
+public class PatternConstraintComponent extends AbstractSimpleConstraintComponent {
String pattern;
String flags;
public PatternConstraintComponent(String pattern, String flags) {
+ super();
this.pattern = pattern;
this.flags = flags;
@@ -67,7 +69,10 @@ String getSparqlFilterExpression(Variable variable, boolean negated) {
}
private static String escapeRegexForSparql(String pattern) {
- return pattern.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n");
+ pattern = pattern.replace("\\", "\\\\");
+ pattern = pattern.replace("\"", "\\\"");
+ pattern = pattern.replace("\n", "\\n");
+ return pattern;
}
@Override
@@ -81,8 +86,8 @@ public ConstraintComponent deepClone() {
}
@Override
- Function getFilterAttacher() {
- return (parent) -> new PatternFilter(parent, pattern, flags);
+ Function getFilterAttacher(ConnectionsGroup connectionsGroup) {
+ return (parent) -> new PatternFilter(parent, pattern, flags, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/QualifiedMaxCountConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/QualifiedMaxCountConstraintComponent.java
index bcbfa93250d..6394c2f9114 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/QualifiedMaxCountConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/QualifiedMaxCountConstraintComponent.java
@@ -140,10 +140,11 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode planNode = negated(connectionsGroup, validationSettings, overrideTargetNode, scope);
- planNode = new LeftOuterJoin(target, planNode);
+ planNode = new LeftOuterJoin(target, planNode, connectionsGroup);
- GroupByCountFilter groupByCountFilter = new GroupByCountFilter(planNode, count -> count > qualifiedMaxCount);
- return Unique.getInstance(new TrimToTarget(groupByCountFilter), false);
+ GroupByCountFilter groupByCountFilter = new GroupByCountFilter(planNode, count -> count > qualifiedMaxCount,
+ connectionsGroup);
+ return Unique.getInstance(new TrimToTarget(groupByCountFilter, connectionsGroup), false, connectionsGroup);
}
@@ -168,7 +169,7 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
false, null);
}
- target = Unique.getInstance(new TrimToTarget(target), false);
+ target = Unique.getInstance(new TrimToTarget(target, connectionsGroup), false, connectionsGroup);
PlanNode relevantTargetsWithPath = new BulkedExternalLeftOuterJoin(
target,
@@ -180,13 +181,13 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider,
Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph())
- );
+ validationSettings.getDataGraph()),
+ connectionsGroup);
return new TupleMapper(relevantTargetsWithPath, t -> {
List targetChain = t.getTargetChain(true);
return new ValidationTuple(targetChain, Scope.propertyShape, false, validationSettings.getDataGraph());
- });
+ }, connectionsGroup);
};
@@ -197,7 +198,7 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
scope
);
- PlanNode invalid = Unique.getInstance(planNode, false);
+ PlanNode invalid = Unique.getInstance(planNode, false, connectionsGroup);
PlanNode allTargetsPlan;
@@ -213,7 +214,8 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
false, null);
}
- allTargetsPlan = Unique.getInstance(new TrimToTarget(allTargetsPlan), false);
+ allTargetsPlan = Unique.getInstance(new TrimToTarget(allTargetsPlan, connectionsGroup), false,
+ connectionsGroup);
allTargetsPlan = new BulkedExternalLeftOuterJoin(
allTargetsPlan,
@@ -223,10 +225,10 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
.getTargetQueryFragment(new StatementMatcher.Variable("a"), new StatementMatcher.Variable("c"),
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph())
- );
+ validationSettings.getDataGraph()),
+ connectionsGroup);
- invalid = new NotValuesIn(allTargetsPlan, invalid);
+ invalid = new NotValuesIn(allTargetsPlan, invalid, connectionsGroup);
return invalid;
@@ -245,7 +247,9 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
PlanNode subTargets = qualifiedValueShape.getAllTargetsPlan(connectionsGroup, dataGraph, scope,
new StatementMatcher.StableRandomVariableProvider());
- return Unique.getInstance(new TrimToTarget(UnionNode.getInstanceDedupe(allTargets, subTargets)), false);
+ return Unique
+ .getInstance(new TrimToTarget(UnionNode.getInstanceDedupe(connectionsGroup, allTargets, subTargets),
+ connectionsGroup), false, connectionsGroup);
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/QualifiedMinCountConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/QualifiedMinCountConstraintComponent.java
index 60dcca29b01..69c499a0fbc 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/QualifiedMinCountConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/QualifiedMinCountConstraintComponent.java
@@ -143,10 +143,11 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode planNode = negated(connectionsGroup, validationSettings, overrideTargetNode, scope);
- planNode = new LeftOuterJoin(target, planNode);
+ planNode = new LeftOuterJoin(target, planNode, connectionsGroup);
- GroupByCountFilter groupByCountFilter = new GroupByCountFilter(planNode, count -> count < qualifiedMinCount);
- return Unique.getInstance(new TrimToTarget(groupByCountFilter), false);
+ GroupByCountFilter groupByCountFilter = new GroupByCountFilter(planNode, count -> count < qualifiedMinCount,
+ connectionsGroup);
+ return Unique.getInstance(new TrimToTarget(groupByCountFilter, connectionsGroup), false, connectionsGroup);
}
@@ -175,7 +176,7 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
false, null);
}
- target = Unique.getInstance(new TrimToTarget(target), false);
+ target = Unique.getInstance(new TrimToTarget(target, connectionsGroup), false, connectionsGroup);
PlanNode relevantTargetsWithPath = new BulkedExternalLeftOuterJoin(
target,
@@ -187,13 +188,13 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider,
Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph())
- );
+ validationSettings.getDataGraph()),
+ connectionsGroup);
return new TupleMapper(relevantTargetsWithPath, t -> {
List targetChain = t.getTargetChain(true);
return new ValidationTuple(targetChain, Scope.propertyShape, false, validationSettings.getDataGraph());
- });
+ }, connectionsGroup);
};
@@ -204,7 +205,7 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
scope
);
- PlanNode invalid = Unique.getInstance(planNode, false);
+ PlanNode invalid = Unique.getInstance(planNode, false, connectionsGroup);
PlanNode allTargetsPlan;
if (overrideTargetNode == null) {
@@ -223,9 +224,11 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
allTargetsPlan = new ShiftToPropertyShape(getTargetChain()
.getEffectiveTarget(Scope.nodeShape, connectionsGroup.getRdfsSubClassOfReasoner(),
stableRandomVariableProvider)
- .getAllTargets(connectionsGroup, validationSettings.getDataGraph(), Scope.nodeShape));
+ .getAllTargets(connectionsGroup, validationSettings.getDataGraph(), Scope.nodeShape),
+ connectionsGroup);
} else {
- allTargetsPlan = Unique.getInstance(new TrimToTarget(allTargetsPlan), false);
+ allTargetsPlan = Unique.getInstance(new TrimToTarget(allTargetsPlan, connectionsGroup), false,
+ connectionsGroup);
allTargetsPlan = new BulkedExternalLeftOuterJoin(
allTargetsPlan,
connectionsGroup.getBaseConnection(),
@@ -236,11 +239,11 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider,
Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
- validationSettings.getDataGraph())
- );
+ validationSettings.getDataGraph()),
+ connectionsGroup);
}
- invalid = new NotValuesIn(allTargetsPlan, invalid);
+ invalid = new NotValuesIn(allTargetsPlan, invalid, connectionsGroup);
return invalid;
@@ -259,7 +262,9 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
PlanNode subTargets = qualifiedValueShape.getAllTargetsPlan(connectionsGroup, dataGraph, scope,
new StatementMatcher.StableRandomVariableProvider());
- return Unique.getInstance(new TrimToTarget(UnionNode.getInstanceDedupe(allTargets, subTargets)), false);
+ return Unique
+ .getInstance(new TrimToTarget(UnionNode.getInstanceDedupe(connectionsGroup, allTargets, subTargets),
+ connectionsGroup), false, connectionsGroup);
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/SparqlConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/SparqlConstraintComponent.java
index 3d60e6f98a6..512ae5b338b 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/SparqlConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/SparqlConstraintComponent.java
@@ -14,7 +14,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
@@ -37,10 +36,8 @@
import org.eclipse.rdf4j.sail.shacl.ast.ValidationQuery;
import org.eclipse.rdf4j.sail.shacl.ast.paths.Path;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AllTargetsPlanNode;
-import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalInnerJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeProvider;
-import org.eclipse.rdf4j.sail.shacl.ast.planNodes.ShiftToPropertyShape;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.SparqlConstraintSelect;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.Unique;
import org.eclipse.rdf4j.sail.shacl.ast.targets.EffectiveTarget;
@@ -162,13 +159,22 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode allTargets;
if (overrideTargetNode != null) {
- allTargets = getPlanNodeForOverrideTargetNode(connectionsGroup, validationSettings, overrideTargetNode,
+ allTargets = getPlanNodeForOverrideTargetNode(
+ connectionsGroup,
+ validationSettings,
+ overrideTargetNode,
scope,
- stableRandomVariableProvider, effectiveTarget, getTargetChain().getPath());
+ effectiveTarget
+ );
+
} else {
allTargets = effectiveTarget.getAllTargets(connectionsGroup, validationSettings.getDataGraph(), scope);
}
+ if (effectiveTarget.size() > 1) {
+ allTargets = Unique.getInstance(allTargets, true, connectionsGroup);
+ }
+
return new SparqlConstraintSelect(connectionsGroup.getBaseConnection(), allTargets, select, scope,
validationSettings.getDataGraph(), produceValidationReports, this, shape);
@@ -176,21 +182,22 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
private PlanNode getPlanNodeForOverrideTargetNode(ConnectionsGroup connectionsGroup,
ValidationSettings validationSettings, PlanNodeProvider overrideTargetNode, Scope scope,
- StatementMatcher.StableRandomVariableProvider stableRandomVariableProvider, EffectiveTarget effectiveTarget,
- Optional path) {
+ EffectiveTarget effectiveTarget) {
PlanNode planNode;
+ assert scope != null;
+
+ PlanNode overrideTargetPlanNode = overrideTargetNode.getPlanNode();
if (scope == Scope.nodeShape) {
- PlanNode overrideTargetPlanNode = overrideTargetNode.getPlanNode();
if (overrideTargetPlanNode instanceof AllTargetsPlanNode) {
- PlanNode allTargets = effectiveTarget.getAllTargets(connectionsGroup,
- validationSettings.getDataGraph(), scope);
-
- return Unique.getInstance(allTargets, true);
+ return effectiveTarget.getAllTargets(connectionsGroup, validationSettings.getDataGraph(), scope);
} else {
- return effectiveTarget.extend(overrideTargetPlanNode, connectionsGroup,
- validationSettings.getDataGraph(), scope,
+ return effectiveTarget.extend(
+ overrideTargetPlanNode,
+ connectionsGroup,
+ validationSettings.getDataGraph(),
+ scope,
EffectiveTarget.Extend.right,
false,
null
@@ -199,36 +206,16 @@ private PlanNode getPlanNodeForOverrideTargetNode(ConnectionsGroup connectionsGr
}
} else {
- PlanNode overrideTargetPlanNode = overrideTargetNode.getPlanNode();
if (overrideTargetPlanNode instanceof AllTargetsPlanNode) {
- // We are cheating a bit here by retrieving all the targets and values at the same time by
- // pretending to be in node shape scope and then shifting the results back to property shape scope
- PlanNode allTargets = getTargetChain()
- .getEffectiveTarget(Scope.nodeShape,
- connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider)
- .getAllTargets(connectionsGroup, validationSettings.getDataGraph(), Scope.nodeShape);
- allTargets = new ShiftToPropertyShape(allTargets);
-
- return Unique.getInstance(allTargets, true);
-
+ return effectiveTarget.getAllTargets(connectionsGroup, validationSettings.getDataGraph(), scope);
} else {
overrideTargetPlanNode = effectiveTarget.extend(overrideTargetPlanNode, connectionsGroup,
validationSettings.getDataGraph(), scope,
EffectiveTarget.Extend.right, false, null);
- planNode = new BulkedExternalInnerJoin(overrideTargetPlanNode,
- connectionsGroup.getBaseConnection(),
- validationSettings.getDataGraph(), path.get()
- .getTargetQueryFragment(new StatementMatcher.Variable("a"),
- new StatementMatcher.Variable("c"),
- connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider,
- Set.of()),
- false, null,
- BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph())
- );
- planNode = connectionsGroup.getCachedNodeFor(planNode);
+ planNode = connectionsGroup.getCachedNodeFor(overrideTargetPlanNode);
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/UniqueLangConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/UniqueLangConstraintComponent.java
index b1ac31d712a..453ff412372 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/UniqueLangConstraintComponent.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/UniqueLangConstraintComponent.java
@@ -140,12 +140,12 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
Set.of()),
false,
null,
- BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph())
+ BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
- );
+ connectionsGroup);
- PlanNode nonUniqueTargetLang = new NonUniqueTargetLang(relevantTargetsWithPath);
- return Unique.getInstance(new TrimToTarget(nonUniqueTargetLang), false);
+ PlanNode nonUniqueTargetLang = new NonUniqueTargetLang(relevantTargetsWithPath, connectionsGroup);
+ return Unique.getInstance(new TrimToTarget(nonUniqueTargetLang, connectionsGroup), false, connectionsGroup);
}
if (connectionsGroup.getStats().wasEmptyBeforeTransaction()) {
@@ -154,10 +154,11 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode addedByPath = path.get().getAllAdded(connectionsGroup, validationSettings.getDataGraph(), null);
- PlanNode innerJoin = new InnerJoin(addedTargets, addedByPath).getJoined(UnBufferedPlanNode.class);
+ PlanNode innerJoin = new InnerJoin(addedTargets, addedByPath, connectionsGroup)
+ .getJoined(UnBufferedPlanNode.class);
- PlanNode nonUniqueTargetLang = new NonUniqueTargetLang(innerJoin);
- return Unique.getInstance(new TrimToTarget(nonUniqueTargetLang), false);
+ PlanNode nonUniqueTargetLang = new NonUniqueTargetLang(innerJoin, connectionsGroup);
+ return Unique.getInstance(new TrimToTarget(nonUniqueTargetLang, connectionsGroup), false, connectionsGroup);
}
PlanNode addedTargets = effectiveTarget.getPlanNode(connectionsGroup, validationSettings.getDataGraph(), scope,
@@ -166,17 +167,18 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode addedByPath = path.get().getAllAdded(connectionsGroup, validationSettings.getDataGraph(), null);
addedByPath = effectiveTarget.getTargetFilter(connectionsGroup,
- validationSettings.getDataGraph(), Unique.getInstance(new TrimToTarget(addedByPath), false));
+ validationSettings.getDataGraph(),
+ Unique.getInstance(new TrimToTarget(addedByPath, connectionsGroup), false, connectionsGroup));
addedByPath = effectiveTarget.extend(addedByPath, connectionsGroup, validationSettings.getDataGraph(), scope,
EffectiveTarget.Extend.left, false,
null);
- PlanNode mergeNode = UnionNode.getInstance(addedTargets, addedByPath);
+ PlanNode mergeNode = UnionNode.getInstance(connectionsGroup, addedTargets, addedByPath);
- mergeNode = new TrimToTarget(mergeNode);
+ mergeNode = new TrimToTarget(mergeNode, connectionsGroup);
- PlanNode allRelevantTargets = Unique.getInstance(mergeNode, false);
+ PlanNode allRelevantTargets = Unique.getInstance(mergeNode, false, connectionsGroup);
PlanNode relevantTargetsWithPath = new BulkedExternalInnerJoin(
allRelevantTargets,
@@ -186,13 +188,13 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
false,
null,
- BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph())
+ BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
- );
+ connectionsGroup);
- PlanNode nonUniqueTargetLang = new NonUniqueTargetLang(relevantTargetsWithPath);
+ PlanNode nonUniqueTargetLang = new NonUniqueTargetLang(relevantTargetsWithPath, connectionsGroup);
- return Unique.getInstance(new TrimToTarget(nonUniqueTargetLang), false);
+ return Unique.getInstance(new TrimToTarget(nonUniqueTargetLang, connectionsGroup), false, connectionsGroup);
}
@@ -205,7 +207,8 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]
stableRandomVariableProvider)
.getPlanNode(connectionsGroup, dataGraph, Scope.nodeShape, true, null);
- return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan), true);
+ return Unique.getInstance(new ShiftToPropertyShape(allTargetsPlan, connectionsGroup), true,
+ connectionsGroup);
}
return EmptyNode.getInstance();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/paths/AlternativePath.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/paths/AlternativePath.java
index 76a8aa8f77e..2d40f5430f0 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/paths/AlternativePath.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/paths/AlternativePath.java
@@ -81,7 +81,7 @@ public PlanNode getAllAdded(ConnectionsGroup connectionsGroup, Resource[] dataGr
return paths
.stream()
.map(p -> p.getAllAdded(connectionsGroup, dataGraph, planNodeWrapper))
- .reduce(UnionNode::getInstance)
+ .reduce((nodes, nodes2) -> UnionNode.getInstance(connectionsGroup, nodes, nodes2))
.orElse(EmptyNode.getInstance());
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/paths/InversePath.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/paths/InversePath.java
index b7231ced53c..eb2b3f72be4 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/paths/InversePath.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/paths/InversePath.java
@@ -59,7 +59,7 @@ public PlanNode getAllAdded(ConnectionsGroup connectionsGroup, Resource[] dataGr
PlanNode added = path.getAllAdded(connectionsGroup, dataGraph, null);
added = new TupleMapper(added, t -> new ValidationTuple(t.getValue(), t.getActiveTarget(),
- ConstraintComponent.Scope.propertyShape, true, dataGraph));
+ ConstraintComponent.Scope.propertyShape, true, dataGraph), connectionsGroup);
if (planNodeWrapper != null) {
added = planNodeWrapper.apply(added);
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/AbstractBulkJoinPlanNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/AbstractBulkJoinPlanNode.java
index fda18eb1b72..dab0aac9d7e 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/AbstractBulkJoinPlanNode.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/AbstractBulkJoinPlanNode.java
@@ -11,6 +11,7 @@
package org.eclipse.rdf4j.sail.shacl.ast.planNodes;
import java.util.ArrayDeque;
+import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -50,7 +51,7 @@ TupleExpr parseQuery(String query) {
return SparqlQueryParserCache.get(completeQuery);
}
- void runQuery(ArrayDeque left, ArrayDeque right, SailConnection connection,
+ void runQuery(Collection left, ArrayDeque right, SailConnection connection,
TupleExpr parsedQuery, Dataset dataset, Resource[] dataGraph, boolean skipBasedOnPreviousConnection,
SailConnection previousStateConnection) {
List newBindindingSet = buildBindingSets(left, connection, skipBasedOnPreviousConnection,
@@ -92,7 +93,7 @@ public void meet(BindingSetAssignment node) {
});
}
- private List buildBindingSets(ArrayDeque left, SailConnection connection,
+ private List buildBindingSets(Collection left, SailConnection connection,
boolean skipBasedOnPreviousConnection, SailConnection previousStateConnection, Resource[] dataGraph) {
return left.stream()
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BindSelect.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BindSelect.java
index d77d8223321..6f3a1ae607d 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BindSelect.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BindSelect.java
@@ -41,6 +41,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.AbstractConstraintComponent;
import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.ConstraintComponent;
import org.eclipse.rdf4j.sail.shacl.ast.targets.EffectiveTarget;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,7 +75,7 @@ public class BindSelect implements PlanNode {
public BindSelect(SailConnection connection, Resource[] dataGraph, SparqlFragment query,
List> vars, PlanNode source,
List varNames, ConstraintComponent.Scope scope, int bulkSize, EffectiveTarget.Extend direction,
- boolean includePropertyShapeValues) {
+ boolean includePropertyShapeValues, ConnectionsGroup connectionsGroup) {
this.connection = connection;
assert this.connection != null;
this.mapper = (bindingSet) -> new ValidationTuple(bindingSet, varNames, scope, includePropertyShapeValues,
@@ -83,13 +84,13 @@ public BindSelect(SailConnection connection, Resource[] dataGraph, SparqlFragmen
this.scope = scope;
this.vars = vars;
this.bulkSize = bulkSize;
- this.source = PlanNodeHelper.handleSorting(this, source);
+ this.source = PlanNodeHelper.handleSorting(this, source, connectionsGroup);
if (query.getFragment().trim().equals("")) {
throw new IllegalStateException();
}
- this.query = StatementMatcher.StableRandomVariableProvider.normalize(query.getFragment());
+ this.query = StatementMatcher.StableRandomVariableProvider.normalize(query.getFragment(), vars, List.of());
this.prefixes = query.getNamespacesForSparql();
this.direction = direction;
this.includePropertyShapeValues = includePropertyShapeValues;
@@ -322,13 +323,13 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
// added/removed connections are always newly minted per plan node, so we instead need to compare the underlying
// sail
- if (connection instanceof MemoryStoreConnection) {
- stringBuilder
- .append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> " + getId())
- .append("\n");
- } else {
- stringBuilder.append(System.identityHashCode(connection) + " -> " + getId()).append("\n");
- }
+// if (connection instanceof MemoryStoreConnection) {
+// stringBuilder
+// .append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> " + getId())
+// .append("\n");
+// } else {
+ stringBuilder.append(System.identityHashCode(connection) + " -> " + getId()).append("\n");
+// }
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BufferedSplitter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BufferedSplitter.java
index df62ca822f0..ef571fc554f 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BufferedSplitter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BufferedSplitter.java
@@ -41,18 +41,34 @@ public class BufferedSplitter implements PlanNodeProvider {
private final boolean cached;
private volatile List tuplesBuffer;
private long id = -1;
+ private boolean printed;
- public BufferedSplitter(PlanNode parent, boolean cached) {
+ private BufferedSplitter(PlanNode parent, boolean cached) {
this.parent = parent;
this.cached = cached;
id = idCounter.incrementAndGet();
-
}
- public BufferedSplitter(PlanNode parent) {
+ private BufferedSplitter(PlanNode parent) {
this(parent, true);
}
+ public static BufferedSplitter getInstance(PlanNode parent) {
+ if (parent instanceof BufferedSplitterPlaneNode
+ && ((BufferedSplitterPlaneNode) parent).bufferedSplitter.cached == true) {
+ return ((BufferedSplitterPlaneNode) parent).bufferedSplitter;
+ }
+ return new BufferedSplitter(parent);
+ }
+
+ public static BufferedSplitter getInstance(PlanNode parent, boolean cached) {
+ if (parent instanceof BufferedSplitterPlaneNode
+ && ((BufferedSplitterPlaneNode) parent).bufferedSplitter.cached == cached) {
+ return ((BufferedSplitterPlaneNode) parent).bufferedSplitter;
+ }
+ return new BufferedSplitter(parent, cached);
+ }
+
private synchronized void init() {
if (tuplesBuffer == null) {
tuplesBuffer = new ArrayList<>();
@@ -156,10 +172,10 @@ public int depth() {
@Override
public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
- if (printed) {
+ if (bufferedSplitter.printed) {
return;
}
- printed = true;
+ bufferedSplitter.printed = true;
stringBuilder.append(getId() + " [label=\"" + StringEscapeUtils.escapeJava(this.toString()) + "\"];")
.append("\n");
stringBuilder.append(bufferedSplitter.parent.getId() + " -> " + getId()).append("\n");
@@ -173,7 +189,7 @@ public String getId() {
@Override
public String toString() {
- return "BufferedSplitter";
+ return "BufferedSplitter" + (cached ? " (cached)" : "");
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BulkedExternalInnerJoin.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BulkedExternalInnerJoin.java
index 822703f9a71..4fa535418b1 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BulkedExternalInnerJoin.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BulkedExternalInnerJoin.java
@@ -12,20 +12,24 @@
package org.eclipse.rdf4j.sail.shacl.ast.planNodes;
import java.util.ArrayDeque;
+import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.Dataset;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
+import org.eclipse.rdf4j.query.algebra.evaluation.iterator.PeekMarkIterator;
import org.eclipse.rdf4j.sail.SailConnection;
-import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection;
import org.eclipse.rdf4j.sail.shacl.ast.SparqlFragment;
import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher;
import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.ConstraintComponent;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -57,13 +61,13 @@ public class BulkedExternalInnerJoin extends AbstractBulkJoinPlanNode {
public BulkedExternalInnerJoin(PlanNode leftNode, SailConnection connection, Resource[] dataGraph,
SparqlFragment query,
boolean skipBasedOnPreviousConnection, SailConnection previousStateConnection,
- Function mapper) {
+ Function mapper, ConnectionsGroup connectionsGroup) {
super();
assert !skipBasedOnPreviousConnection || previousStateConnection != null;
- this.leftNode = PlanNodeHelper.handleSorting(this, leftNode);
+ this.leftNode = PlanNodeHelper.handleSorting(this, leftNode, connectionsGroup);
this.query = query.getNamespacesForSparql() + StatementMatcher.StableRandomVariableProvider
- .normalize(query.getFragment());
+ .normalize(query.getFragment(), List.of(), List.of());
this.connection = connection;
assert this.connection != null;
this.skipBasedOnPreviousConnection = skipBasedOnPreviousConnection;
@@ -90,17 +94,17 @@ public static Function getMapper(String a, String c
public CloseableIteration extends ValidationTuple> iterator() {
return new LoggingCloseableIteration(this, validationExecutionLogger) {
- ArrayDeque left;
+ LinkedHashMap left;
ArrayDeque right;
ArrayDeque joined;
- private CloseableIteration extends ValidationTuple> leftNodeIterator;
+ private PeekMarkIterator extends ValidationTuple> leftNodeIterator;
@Override
protected void init() {
- left = new ArrayDeque<>(BULK_SIZE);
+ left = new LinkedHashMap<>(BULK_SIZE * 3);
right = new ArrayDeque<>(BULK_SIZE);
joined = new ArrayDeque<>(BULK_SIZE);
- leftNodeIterator = leftNode.iterator();
+ leftNodeIterator = new PeekMarkIterator<>(leftNode.iterator());
}
private void calculateNext() {
@@ -112,57 +116,30 @@ private void calculateNext() {
while (joined.isEmpty() && leftNodeIterator.hasNext()) {
while (left.size() < BULK_SIZE && leftNodeIterator.hasNext()) {
- left.addFirst(leftNodeIterator.next());
+ ValidationTuple next = leftNodeIterator.next();
+ ValidationTuple previousValue = left.put(next.getActiveTarget(), next);
+ assert previousValue == null : "We dont support duplicates on the left side of the join";
}
if (parsedQuery == null) {
parsedQuery = parseQuery(query);
}
- runQuery(left, right, connection, parsedQuery, dataset, dataGraph, skipBasedOnPreviousConnection,
+ runQuery(left.values(), right, connection, parsedQuery, dataset, dataGraph,
+ skipBasedOnPreviousConnection,
previousStateConnection);
while (!right.isEmpty()) {
- ValidationTuple leftPeek = left.peekLast();
+ ValidationTuple rightPeek = right.getLast();
+ ValidationTuple leftPeek = left.get(rightPeek.getActiveTarget());
- ValidationTuple rightPeek = right.peekLast();
-
- assert leftPeek != null;
- assert rightPeek != null;
-
- assert leftPeek.getActiveTarget() != null;
- assert rightPeek.getActiveTarget() != null;
-
- if (rightPeek.sameTargetAs(leftPeek)) {
+ if (leftPeek != null) {
// we have a join !
joined.addLast(ValidationTupleHelper.join(leftPeek, rightPeek));
right.removeLast();
-
- ValidationTuple rightPeek2 = right.peekLast();
-
- if (rightPeek2 == null || !rightPeek2.sameTargetAs(leftPeek)) {
- // no more to join from right, pop left so we don't print it again.
-
- left.removeLast();
- }
} else {
- int compare = rightPeek.compareActiveTarget(leftPeek);
-
- if (compare < 0) {
- if (right.isEmpty()) {
- throw new IllegalStateException();
- }
-
- right.removeLast();
-
- } else {
- if (left.isEmpty()) {
- throw new IllegalStateException();
- }
- left.removeLast();
-
- }
+ right.removeLast();
}
}
@@ -212,13 +189,13 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
// added/removed connections are always newly minted per plan node, so we instead need to compare the underlying
// sail
- if (connection instanceof MemoryStoreConnection) {
- stringBuilder.append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> "
- + getId() + " [label=\"right\"]").append("\n");
- } else {
- stringBuilder.append(System.identityHashCode(connection) + " -> " + getId() + " [label=\"right\"]")
- .append("\n");
- }
+// if (connection instanceof MemoryStoreConnection) {
+// stringBuilder.append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> "
+// + getId() + " [label=\"right\"]").append("\n");
+// } else {
+ stringBuilder.append(System.identityHashCode(connection) + " -> " + getId() + " [label=\"right\"]")
+ .append("\n");
+// }
if (skipBasedOnPreviousConnection) {
@@ -272,4 +249,14 @@ public int hashCode() {
return Objects.hash(super.hashCode(), connection, dataset, leftNode, skipBasedOnPreviousConnection,
previousStateConnection, query);
}
+
+ @Override
+ public boolean producesSorted() {
+ return leftNode.producesSorted();
+ }
+
+ @Override
+ public boolean requiresSorted() {
+ return false;
+ }
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BulkedExternalLeftOuterJoin.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BulkedExternalLeftOuterJoin.java
index 3035de45625..ef5689508df 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BulkedExternalLeftOuterJoin.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BulkedExternalLeftOuterJoin.java
@@ -12,6 +12,7 @@
package org.eclipse.rdf4j.sail.shacl.ast.planNodes;
import java.util.ArrayDeque;
+import java.util.List;
import java.util.Objects;
import java.util.function.Function;
@@ -21,10 +22,11 @@
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.Dataset;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
+import org.eclipse.rdf4j.query.algebra.evaluation.iterator.PeekMarkIterator;
import org.eclipse.rdf4j.sail.SailConnection;
-import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection;
import org.eclipse.rdf4j.sail.shacl.ast.SparqlFragment;
import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -44,12 +46,12 @@ public class BulkedExternalLeftOuterJoin extends AbstractBulkJoinPlanNode {
public BulkedExternalLeftOuterJoin(PlanNode leftNode, SailConnection connection, Resource[] dataGraph,
SparqlFragment query,
- Function mapper) {
+ Function mapper, ConnectionsGroup connectionsGroup) {
super();
- leftNode = PlanNodeHelper.handleSorting(this, leftNode);
+ leftNode = PlanNodeHelper.handleSorting(this, leftNode, connectionsGroup);
this.leftNode = leftNode;
this.query = query.getNamespacesForSparql()
- + StatementMatcher.StableRandomVariableProvider.normalize(query.getFragment());
+ + StatementMatcher.StableRandomVariableProvider.normalize(query.getFragment(), List.of(), List.of());
this.connection = connection;
assert this.connection != null;
this.mapper = mapper;
@@ -64,13 +66,13 @@ public CloseableIteration extends ValidationTuple> iterator() {
ArrayDeque left;
ArrayDeque right;
- private CloseableIteration extends ValidationTuple> leftNodeIterator;
+ private PeekMarkIterator extends ValidationTuple> leftNodeIterator;
@Override
protected void init() {
left = new ArrayDeque<>(BULK_SIZE);
right = new ArrayDeque<>(BULK_SIZE);
- leftNodeIterator = leftNode.iterator();
+ leftNodeIterator = new PeekMarkIterator<>(leftNode.iterator());
}
private void calculateNext() {
@@ -80,6 +82,15 @@ private void calculateNext() {
}
while (left.size() < BULK_SIZE && leftNodeIterator.hasNext()) {
+ if (!left.isEmpty()) {
+ ValidationTuple peek = leftNodeIterator.peek();
+ if (peek.sameTargetAs(left.getFirst())) {
+ // stop if we detect a duplicate target since we only support distinct targets on the left
+ // side of the join
+ assert false : "Current and next left target is the same: " + peek + " " + left.getFirst();
+ break;
+ }
+ }
left.addFirst(leftNodeIterator.next());
}
@@ -172,13 +183,13 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
// added/removed connections are always newly minted per plan node, so we instead need to compare the underlying
// sail
- if (connection instanceof MemoryStoreConnection) {
- stringBuilder.append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> "
- + getId() + " [label=\"right\"]").append("\n");
- } else {
- stringBuilder.append(System.identityHashCode(connection) + " -> " + getId() + " [label=\"right\"]")
- .append("\n");
- }
+// if (connection instanceof MemoryStoreConnection) {
+// stringBuilder.append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> "
+// + getId() + " [label=\"right\"]").append("\n");
+// } else {
+ stringBuilder.append(System.identityHashCode(connection) + " -> " + getId() + " [label=\"right\"]")
+ .append("\n");
+// }
stringBuilder.append(leftNode.getId() + " -> " + getId() + " [label=\"left\"]").append("\n");
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/DatatypeFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/DatatypeFilter.java
index eba54296981..deeb33dfe2d 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/DatatypeFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/DatatypeFilter.java
@@ -17,6 +17,7 @@
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.base.CoreDatatype;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,8 +32,8 @@ public class DatatypeFilter extends FilterPlanNode {
private final CoreDatatype.XSD xsdDatatype;
private StackTraceElement[] stackTrace;
- public DatatypeFilter(PlanNode parent, IRI datatype) {
- super(parent);
+ public DatatypeFilter(PlanNode parent, IRI datatype, ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.datatype = datatype;
this.xsdDatatype = CoreDatatype.from(datatype).asXSDDatatype().orElse(null);
// stackTrace = Thread.currentThread().getStackTrace();
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/EqualsJoin.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/EqualsJoin.java
index 4808927e750..3254c0b286f 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/EqualsJoin.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/EqualsJoin.java
@@ -14,6 +14,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class EqualsJoin implements PlanNode {
private final PlanNode left;
@@ -22,9 +23,9 @@ public class EqualsJoin implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public EqualsJoin(PlanNode left, PlanNode right, boolean useAsFilter) {
- this.left = PlanNodeHelper.handleSorting(this, left);
- this.right = PlanNodeHelper.handleSorting(this, right);
+ public EqualsJoin(PlanNode left, PlanNode right, boolean useAsFilter, ConnectionsGroup connectionsGroup) {
+ this.left = PlanNodeHelper.handleSorting(this, left, connectionsGroup);
+ this.right = PlanNodeHelper.handleSorting(this, right, connectionsGroup);
this.useAsFilter = useAsFilter;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/EqualsJoinValue.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/EqualsJoinValue.java
index 3551c681d4b..a8ee407df5a 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/EqualsJoinValue.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/EqualsJoinValue.java
@@ -14,6 +14,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class EqualsJoinValue implements PlanNode {
private final PlanNode left;
@@ -23,9 +24,9 @@ public class EqualsJoinValue implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public EqualsJoinValue(PlanNode left, PlanNode right, boolean useAsFilter) {
- this.left = PlanNodeHelper.handleSorting(this, left);
- this.right = PlanNodeHelper.handleSorting(this, right);
+ public EqualsJoinValue(PlanNode left, PlanNode right, boolean useAsFilter, ConnectionsGroup connectionsGroup) {
+ this.left = PlanNodeHelper.handleSorting(this, left, connectionsGroup);
+ this.right = PlanNodeHelper.handleSorting(this, right, connectionsGroup);
this.useAsFilter = useAsFilter;
// this.stackTrace = Thread.currentThread().getStackTrace();
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ExternalFilterByQuery.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ExternalFilterByQuery.java
index 9336f1d426c..81f558766a5 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ExternalFilterByQuery.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ExternalFilterByQuery.java
@@ -11,6 +11,7 @@
package org.eclipse.rdf4j.sail.shacl.ast.planNodes;
+import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
@@ -26,6 +27,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.SparqlFragment;
import org.eclipse.rdf4j.sail.shacl.ast.SparqlQueryParserCache;
import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,8 +49,9 @@ public class ExternalFilterByQuery extends FilterPlanNode {
public ExternalFilterByQuery(SailConnection connection, Resource[] dataGraph, PlanNode parent,
SparqlFragment queryFragment,
StatementMatcher.Variable queryVariable,
- Function filterOn, BiFunction map) {
- super(parent);
+ Function filterOn, BiFunction map,
+ ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.connection = connection;
assert this.connection != null;
this.queryVariable = queryVariable;
@@ -57,15 +60,15 @@ public ExternalFilterByQuery(SailConnection connection, Resource[] dataGraph, Pl
if (map != null) {
this.queryString = queryFragment.getNamespacesForSparql()
+ StatementMatcher.StableRandomVariableProvider.normalize("SELECT * "
- + " WHERE {\n" + queryFragment.getFragment() + "\n}");
+ + " WHERE {\n" + queryFragment.getFragment() + "\n}", List.of(queryVariable), List.of());
} else {
this.queryString = queryFragment.getNamespacesForSparql()
+ StatementMatcher.StableRandomVariableProvider
.normalize("SELECT " + queryVariable.asSparqlVariable()
- + " WHERE {\n" + queryFragment.getFragment() + "\n}");
+ + " WHERE {\n" + queryFragment.getFragment() + "\n}", List.of(queryVariable),
+ List.of());
}
-
try {
this.query = SparqlQueryParserCache.get(queryString);
} catch (MalformedQueryException e) {
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicate.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicate.java
index 3072316acdf..8c5b49b0218 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicate.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicate.java
@@ -25,6 +25,7 @@
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.sail.SailConnection;
import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -45,9 +46,9 @@ public enum On {
}
public FilterByPredicate(SailConnection connection, Set filterOnPredicates, PlanNode parent,
- On on, Resource[] dataGraph) {
+ On on, Resource[] dataGraph, ConnectionsGroup connectionsGroup) {
this.dataGraph = dataGraph;
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.connection = connection;
assert this.connection != null;
this.filterOnPredicates = filterOnPredicates;
@@ -174,13 +175,13 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
// added/removed connections are always newly minted per plan node, so we instead need to compare the underlying
// sail
- if (connection instanceof MemoryStoreConnection) {
- stringBuilder.append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> "
- + getId() + " [label=\"filter source\"]").append("\n");
- } else {
- stringBuilder.append(System.identityHashCode(connection) + " -> " + getId() + " [label=\"filter source\"]")
- .append("\n");
- }
+// if (connection instanceof MemoryStoreConnection) {
+// stringBuilder.append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> "
+// + getId() + " [label=\"filter source\"]").append("\n");
+// } else {
+ stringBuilder.append(System.identityHashCode(connection) + " -> " + getId() + " [label=\"filter source\"]")
+ .append("\n");
+// }
parent.getPlanAsGraphvizDot(stringBuilder);
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicateObject.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicateObject.java
index 61efae71219..9a44baba198 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicateObject.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicateObject.java
@@ -14,6 +14,7 @@
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
@@ -22,7 +23,12 @@
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.sail.SailConnection;
+import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
/**
* @author Håvard Ottestad
@@ -41,11 +47,13 @@ public class FilterByPredicateObject implements PlanNode {
private ValidationExecutionLogger validationExecutionLogger;
private final Resource[] dataGraph;
+ private final Cache cache;
+
public FilterByPredicateObject(SailConnection connection, Resource[] dataGraph, IRI filterOnPredicate,
Set filterOnObject, PlanNode parent, boolean returnMatching, FilterOn filterOn,
- boolean includeInferred) {
+ boolean includeInferred, ConnectionsGroup connectionsGroup) {
this.dataGraph = dataGraph;
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.connection = connection;
assert this.connection != null;
this.includeInferred = includeInferred;
@@ -53,6 +61,13 @@ public FilterByPredicateObject(SailConnection connection, Resource[] dataGraph,
this.filterOnObject = filterOnObject;
this.filterOn = filterOn;
this.returnMatching = returnMatching;
+
+ if (connection instanceof MemoryStoreConnection) {
+ cache = null;
+ } else {
+ cache = CacheBuilder.newBuilder().maximumSize(10000).build();
+ }
+
// this.stackTrace = Thread.currentThread().getStackTrace();
}
@@ -195,11 +210,36 @@ private boolean matches(Value subject, IRI filterOnPredicate, Resource[] filterO
}
if (subject.isResource()) {
- for (Resource object : filterOnObject) {
- if (connection.hasStatement(((Resource) subject), filterOnPredicate, object, includeInferred,
- dataGraph)) {
- return true;
+
+ if (cache == null) {
+ return matchesUnCached((Resource) subject, filterOnPredicate, filterOnObject);
+ } else {
+ return matchesCached((Resource) subject, filterOnPredicate, filterOnObject);
+ }
+
+ }
+ return false;
+ }
+
+ private Boolean matchesCached(Resource subject, IRI filterOnPredicate, Resource[] filterOnObject) {
+ try {
+ return cache.get(subject, () -> matchesUnCached(subject, filterOnPredicate, filterOnObject));
+ } catch (ExecutionException e) {
+ if (e.getCause() != null) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw ((RuntimeException) e.getCause());
}
+ throw new SailException(e.getCause());
+ }
+ throw new SailException(e);
+ }
+ }
+
+ private boolean matchesUnCached(Resource subject, IRI filterOnPredicate, Resource[] filterOnObject) {
+ for (Resource object : filterOnObject) {
+ if (connection.hasStatement(subject, filterOnPredicate, object, includeInferred,
+ dataGraph)) {
+ return true;
}
}
return false;
@@ -222,13 +262,13 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
// added/removed connections are always newly minted per plan node, so we instead need to compare the underlying
// sail
- if (connection instanceof MemoryStoreConnection) {
- stringBuilder.append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> "
- + getId() + " [label=\"filter source\"]").append("\n");
- } else {
- stringBuilder.append(System.identityHashCode(connection) + " -> " + getId() + " [label=\"filter source\"]")
- .append("\n");
- }
+// if (connection instanceof MemoryStoreConnection) {
+// stringBuilder.append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> "
+// + getId() + " [label=\"filter source\"]").append("\n");
+// } else {
+ stringBuilder.append(System.identityHashCode(connection) + " -> " + getId() + " [label=\"filter source\"]")
+ .append("\n");
+// }
parent.getPlanAsGraphvizDot(stringBuilder);
}
@@ -301,8 +341,10 @@ public int hashCode() {
@Override
public String toString() {
- return "ExternalPredicateObjectFilter{" + "filterOnObject=" + filterOnObject + ", filterOnPredicate="
- + filterOnPredicate + ", filterOn=" + filterOn + ", parent=" + parent + ", returnMatching="
+ return "ExternalPredicateObjectFilter{" + "filterOnObject=" + PlanNode.prefix(filterOnObject)
+ + ", filterOnPredicate="
+ + PlanNode.prefix(filterOnPredicate) + ", filterOn=" + filterOn + ", returnMatching="
+ returnMatching + '}';
}
+
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterPlanNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterPlanNode.java
index f11004fa25d..a1879503fc4 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterPlanNode.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterPlanNode.java
@@ -16,6 +16,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,8 +38,8 @@ public abstract class FilterPlanNode implements MultiStreamPlanNode, PlanNode {
abstract boolean checkTuple(Reference t);
- public FilterPlanNode(PlanNode parent) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public FilterPlanNode(PlanNode parent, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
}
public PlanNode getTrueNode(Class extends PushablePlanNode> type) {
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterTargetIsObject.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterTargetIsObject.java
index 61961b42de5..bdf07046958 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterTargetIsObject.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterTargetIsObject.java
@@ -18,6 +18,7 @@
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.sail.SailConnection;
import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -27,8 +28,9 @@ public class FilterTargetIsObject extends FilterPlanNode {
private final SailConnection connection;
private final Resource[] dataGraph;
- public FilterTargetIsObject(SailConnection connection, Resource[] dataGraph, PlanNode parent) {
- super(parent);
+ public FilterTargetIsObject(SailConnection connection, Resource[] dataGraph, PlanNode parent,
+ ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.connection = connection;
assert this.connection != null;
this.dataGraph = dataGraph;
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterTargetIsSubject.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterTargetIsSubject.java
index 7ba6fdaef0a..02acb30e90f 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterTargetIsSubject.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterTargetIsSubject.java
@@ -18,6 +18,7 @@
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.sail.SailConnection;
import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -27,8 +28,9 @@ public class FilterTargetIsSubject extends FilterPlanNode {
private final SailConnection connection;
private final Resource[] dataGraph;
- public FilterTargetIsSubject(SailConnection connection, Resource[] dataGraph, PlanNode parent) {
- super(parent);
+ public FilterTargetIsSubject(SailConnection connection, Resource[] dataGraph, PlanNode parent,
+ ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.connection = connection;
assert this.connection != null;
this.dataGraph = dataGraph;
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Formatter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Formatter.java
index 9a40c914d73..e6f182190ea 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Formatter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Formatter.java
@@ -10,11 +10,17 @@
*******************************************************************************/
package org.eclipse.rdf4j.sail.shacl.ast.planNodes;
+import java.util.List;
+
import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Namespace;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.impl.SimpleNamespace;
+import org.eclipse.rdf4j.model.vocabulary.DCAT;
+import org.eclipse.rdf4j.model.vocabulary.FOAF;
import org.eclipse.rdf4j.model.vocabulary.RDF;
-import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.model.vocabulary.SHACL;
+import org.eclipse.rdf4j.model.vocabulary.XSD;
public class Formatter {
@@ -28,20 +34,19 @@ public static String prefix(Value in) {
String namespace = ((IRI) in).getNamespace();
- if (namespace.equals(RDF.NAMESPACE)) {
- return in.toString().replace(RDF.NAMESPACE, RDF.PREFIX + ":");
- }
- if (namespace.equals(RDFS.NAMESPACE)) {
- return in.toString().replace(RDFS.NAMESPACE, RDFS.PREFIX + ":");
- }
- if (namespace.equals(SHACL.NAMESPACE)) {
- return in.toString().replace(SHACL.NAMESPACE, SHACL.PREFIX + ":");
- }
- if (namespace.equals("http://example.com/ns#")) {
- return in.toString().replace("http://example.com/ns#", "ex:");
- }
- if (namespace.equals("http://www.w3.org/2001/XMLSchema#")) {
- return in.toString().replace("http://www.w3.org/2001/XMLSchema#", "xsd:");
+ List namespaces = List.of(
+ RDF.NS,
+ SHACL.NS,
+ FOAF.NS,
+ DCAT.NS,
+ new SimpleNamespace("http://example.com/ns#", "ex"),
+ XSD.NS
+ );
+
+ for (Namespace ns : namespaces) {
+ if (namespace.equals(ns.getName())) {
+ return ns.getPrefix() + ":" + ((IRI) in).getLocalName();
+ }
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/GroupByCountFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/GroupByCountFilter.java
index 2d95a212338..9c4c23d9e8e 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/GroupByCountFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/GroupByCountFilter.java
@@ -16,6 +16,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,8 +32,8 @@ public class GroupByCountFilter implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public GroupByCountFilter(PlanNode parent, Function filter) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public GroupByCountFilter(PlanNode parent, Function filter, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.filter = filter;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/GroupByFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/GroupByFilter.java
index 3f3f7c523d2..765faab3ba0 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/GroupByFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/GroupByFilter.java
@@ -19,6 +19,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -30,8 +31,9 @@ public class GroupByFilter implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public GroupByFilter(PlanNode parent, Function, Boolean> filter) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public GroupByFilter(PlanNode parent, Function, Boolean> filter,
+ ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.filter = filter;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/InnerJoin.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/InnerJoin.java
index 46af91faa94..d6265e37251 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/InnerJoin.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/InnerJoin.java
@@ -19,6 +19,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,9 +42,9 @@ public class InnerJoin implements MultiStreamPlanNode, PlanNode {
private NotifyingPushablePlanNode discardedLeft;
private NotifyingPushablePlanNode discardedRight;
- public InnerJoin(PlanNode left, PlanNode right) {
- this.left = PlanNodeHelper.handleSorting(this, left);
- this.right = PlanNodeHelper.handleSorting(this, right);
+ public InnerJoin(PlanNode left, PlanNode right, ConnectionsGroup connectionsGroup) {
+ this.left = PlanNodeHelper.handleSorting(this, left, connectionsGroup);
+ this.right = PlanNodeHelper.handleSorting(this, right, connectionsGroup);
// this.stackTrace = Thread.currentThread().getStackTrace();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LanguageInFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LanguageInFilter.java
index 58736aee4c4..f12653e4adb 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LanguageInFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LanguageInFilter.java
@@ -19,6 +19,7 @@
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.util.Literals;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,8 +33,9 @@ public class LanguageInFilter extends FilterPlanNode {
private final List languageRanges;
private final Set lowerCaseLanguageIn;
- public LanguageInFilter(PlanNode parent, Set lowerCaseLanguageIn, List languageRanges) {
- super(parent);
+ public LanguageInFilter(PlanNode parent, Set lowerCaseLanguageIn, List languageRanges,
+ ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.lowerCaseLanguageIn = lowerCaseLanguageIn;
this.languageRanges = languageRanges;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LeftOuterJoin.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LeftOuterJoin.java
index b6a4e887f3e..bfe8c47d520 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LeftOuterJoin.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LeftOuterJoin.java
@@ -15,6 +15,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -26,9 +27,9 @@ public class LeftOuterJoin implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public LeftOuterJoin(PlanNode left, PlanNode right) {
- this.left = PlanNodeHelper.handleSorting(this, left);
- this.right = PlanNodeHelper.handleSorting(this, right);
+ public LeftOuterJoin(PlanNode left, PlanNode right, ConnectionsGroup connectionsGroup) {
+ this.left = PlanNodeHelper.handleSorting(this, left, connectionsGroup);
+ this.right = PlanNodeHelper.handleSorting(this, right, connectionsGroup);
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LiteralComparatorFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LiteralComparatorFilter.java
index a59e41f1719..099dfe14f4b 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LiteralComparatorFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/LiteralComparatorFilter.java
@@ -17,6 +17,7 @@
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.query.algebra.Compare;
import org.eclipse.rdf4j.query.algebra.evaluation.util.QueryEvaluationUtility;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -27,8 +28,9 @@ public class LiteralComparatorFilter extends FilterPlanNode {
private final Compare.CompareOp compareOp;
- public LiteralComparatorFilter(PlanNode parent, Literal compareTo, Compare.CompareOp compareOp) {
- super(parent);
+ public LiteralComparatorFilter(PlanNode parent, Literal compareTo, Compare.CompareOp compareOp,
+ ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.compareTo = compareTo;
this.compareOp = compareOp;
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/MaxLengthFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/MaxLengthFilter.java
index c2ef2b5482d..0f07104d20d 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/MaxLengthFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/MaxLengthFilter.java
@@ -14,6 +14,7 @@
import java.util.Objects;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -22,8 +23,8 @@ public class MaxLengthFilter extends FilterPlanNode {
private final long maxLength;
- public MaxLengthFilter(PlanNode parent, long maxLength) {
- super(parent);
+ public MaxLengthFilter(PlanNode parent, long maxLength, ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.maxLength = maxLength;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/MinLengthFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/MinLengthFilter.java
index a8a673cc852..2e3fb3da695 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/MinLengthFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/MinLengthFilter.java
@@ -14,6 +14,7 @@
import java.util.Objects;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -22,8 +23,8 @@ public class MinLengthFilter extends FilterPlanNode {
private final long minLength;
- public MinLengthFilter(PlanNode parent, long minLength) {
- super(parent);
+ public MinLengthFilter(PlanNode parent, long minLength, ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.minLength = minLength;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NodeKindFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NodeKindFilter.java
index 86526d93b9c..957edc9e398 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NodeKindFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NodeKindFilter.java
@@ -15,6 +15,7 @@
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.NodeKindConstraintComponent;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -27,8 +28,9 @@ public class NodeKindFilter extends FilterPlanNode {
private final NodeKindConstraintComponent.NodeKind nodeKind;
- public NodeKindFilter(PlanNode parent, NodeKindConstraintComponent.NodeKind nodeKind) {
- super(parent);
+ public NodeKindFilter(PlanNode parent, NodeKindConstraintComponent.NodeKind nodeKind,
+ ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.nodeKind = nodeKind;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NonUniqueTargetLang.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NonUniqueTargetLang.java
index db07836974d..6ebeb1716ce 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NonUniqueTargetLang.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NonUniqueTargetLang.java
@@ -20,6 +20,7 @@
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* This PlanNode takes a stream of Tuples like: (ex:companyA, "Company A"@en). It assumes that the stream is sorted on
@@ -36,8 +37,8 @@ public class NonUniqueTargetLang implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public NonUniqueTargetLang(PlanNode parent) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public NonUniqueTargetLang(PlanNode parent, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NotValuesIn.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NotValuesIn.java
index d4cb09cc579..553ec6b88eb 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NotValuesIn.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/NotValuesIn.java
@@ -19,6 +19,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class NotValuesIn implements PlanNode {
@@ -27,8 +28,8 @@ public class NotValuesIn implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public NotValuesIn(PlanNode parent, PlanNode notIn) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public NotValuesIn(PlanNode parent, PlanNode notIn, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.notIn = notIn;
}
@@ -116,6 +117,12 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
.append(StringEscapeUtils.escapeJava(this.toString()))
.append("\"];")
.append("\n");
+
+ stringBuilder.append(parent.getId() + " -> " + getId()).append("\n");
+ stringBuilder.append(notIn.getId() + " -> " + getId()).append("\n");
+ parent.getPlanAsGraphvizDot(stringBuilder);
+ notIn.getPlanAsGraphvizDot(stringBuilder);
+
}
@Override
@@ -125,10 +132,7 @@ public String getId() {
@Override
public String toString() {
- return "NotValuesIn{" +
- "parent=" + parent +
- ", notIn=" + notIn +
- '}';
+ return "NotValuesIn";
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PatternFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PatternFilter.java
index ebef3b98ddc..c972ae0e3a0 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PatternFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PatternFilter.java
@@ -14,7 +14,14 @@
import java.util.Objects;
import java.util.regex.Pattern;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.query.algebra.evaluation.util.QueryEvaluationUtility;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -27,8 +34,8 @@ public class PatternFilter extends FilterPlanNode {
private final Pattern pattern;
- public PatternFilter(PlanNode parent, String pattern, String flags) {
- super(parent);
+ public PatternFilter(PlanNode parent, String pattern, String flags, ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
if (flags != null && !flags.isEmpty()) {
int flag = 0b0;
@@ -71,16 +78,49 @@ public PatternFilter(PlanNode parent, String pattern, String flags) {
logger.trace("PatternFilter constructed with pattern: {} and flags: {}", pattern, flags);
} else {
- this.pattern = Pattern.compile(pattern);
+ this.pattern = Pattern.compile(pattern, 0b0);
logger.trace("PatternFilter constructed with pattern: {} and no flags", pattern);
}
}
+ private static Literal str(Value argValue, ValueFactory valueFactory) {
+ if (argValue instanceof IRI || argValue instanceof Triple) {
+ return valueFactory.createLiteral(argValue.toString());
+ } else if (argValue instanceof Literal) {
+ Literal literal = (Literal) argValue;
+
+ if (QueryEvaluationUtility.isSimpleLiteral(literal)) {
+ return literal;
+ } else {
+ return valueFactory.createLiteral(literal.getLabel());
+ }
+ } else {
+ return null;
+ }
+ }
+
@Override
boolean checkTuple(Reference t) {
Value literal = t.get().getValue();
+ literal = str(literal, SimpleValueFactory.getInstance());
- return pattern.matcher(literal.stringValue()).matches();
+ if (literal == null)
+ return false;
+
+ if (QueryEvaluationUtility.isStringLiteral(literal)) {
+ boolean result = pattern.matcher(((Literal) literal).getLabel()).find();
+ if (logger.isTraceEnabled()) {
+ logger.trace("PatternFilter value: \"{}\" with pattern: \"{}\" and result: {}",
+ ((Literal) literal).getLabel().replace("\n", "\\n").replace("\"", "\\\""),
+ pattern.toString().replace("\n", "\\n").replace("\"", "\\\""), result);
+ }
+ return result;
+ }
+
+ if (logger.isTraceEnabled()) {
+ logger.trace("PatternFilter did not match value because value is not a string literal: {}", literal);
+ }
+ return false;
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PlanNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PlanNode.java
index 9af9725b150..919d39323f0 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PlanNode.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PlanNode.java
@@ -11,13 +11,30 @@
package org.eclipse.rdf4j.sail.shacl.ast.planNodes;
+import java.util.Arrays;
+import java.util.Set;
+
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Value;
/**
* @author Håvard Mikkelsen Ottestad
*/
public interface PlanNode {
+ static String prefix(Set filterOnObject) {
+ if (filterOnObject.size() == 1) {
+ return prefix(filterOnObject.iterator().next());
+ }
+
+ return Arrays.toString(filterOnObject.stream().map(PlanNode::prefix).toArray());
+ }
+
+ static String prefix(Value value) {
+ return Formatter.prefix(value);
+ }
+
CloseableIteration extends ValidationTuple> iterator();
int depth();
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PlanNodeHelper.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PlanNodeHelper.java
index b81cb2e68dc..7b98a31981d 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PlanNodeHelper.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/PlanNodeHelper.java
@@ -17,6 +17,7 @@
import org.eclipse.rdf4j.model.vocabulary.RDF4J;
import org.eclipse.rdf4j.query.Dataset;
import org.eclipse.rdf4j.query.impl.SimpleDataset;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class PlanNodeHelper {
@@ -27,14 +28,19 @@ public class PlanNodeHelper {
rdf4jNilDataset.addDefaultGraph(RDF4J.NIL);
}
- public static PlanNode handleSorting(PlanNode child, PlanNode parent) {
- return handleSorting(child.requiresSorted(), parent);
+ public static PlanNode handleSorting(PlanNode child, PlanNode parent, ConnectionsGroup connectionsGroup) {
+ return handleSorting(child.requiresSorted(), parent, connectionsGroup);
}
- public static PlanNode handleSorting(boolean requiresSorted, PlanNode parent) {
+ public static PlanNode handleSorting(boolean requiresSorted, PlanNode parent, ConnectionsGroup connectionsGroup) {
if (requiresSorted) {
if (!parent.producesSorted()) {
- parent = new Sort(parent);
+// if (connectionsGroup != null && (parent instanceof BufferedSplitter.BufferedSplitterPlaneNode ||
+// parent instanceof UnorderedSelect)) {
+// parent = connectionsGroup.getCachedNodeFor(new Sort(parent, connectionsGroup));
+// } else {
+ parent = new Sort(parent, connectionsGroup);
+// }
}
}
return parent;
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ReduceTargets.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ReduceTargets.java
index 69e3b9afef6..4e1a52cb7d7 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ReduceTargets.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ReduceTargets.java
@@ -17,6 +17,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* Takes a parentToReduce and filters away any tuples that have an active target that exists in reductionSource
@@ -28,8 +29,8 @@ public class ReduceTargets implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public ReduceTargets(PlanNode parentToReduce, PlanNode reductionSource) {
- this.parentToReduce = PlanNodeHelper.handleSorting(this, parentToReduce);
+ public ReduceTargets(PlanNode parentToReduce, PlanNode reductionSource, ConnectionsGroup connectionsGroup) {
+ this.parentToReduce = PlanNodeHelper.handleSorting(this, parentToReduce, connectionsGroup);
this.reductionSource = reductionSource;
}
@@ -115,6 +116,11 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
.append(StringEscapeUtils.escapeJava(this.toString()))
.append("\"];")
.append("\n");
+ stringBuilder.append(parentToReduce.getId() + " -> " + getId()).append("\n");
+ stringBuilder.append(reductionSource.getId() + " -> " + getId()).append("\n");
+ parentToReduce.getPlanAsGraphvizDot(stringBuilder);
+ reductionSource.getPlanAsGraphvizDot(stringBuilder);
+
}
@Override
@@ -141,10 +147,7 @@ public boolean requiresSorted() {
@Override
public String toString() {
- return "ReduceTargets{" +
- "parentToReduce=" + parentToReduce +
- ", reductionSource=" + reductionSource +
- '}';
+ return "ReduceTargets";
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Select.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Select.java
index e51c28a7070..157869cbc0d 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Select.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Select.java
@@ -11,6 +11,7 @@
package org.eclipse.rdf4j.sail.shacl.ast.planNodes;
+import java.util.List;
import java.util.Objects;
import java.util.function.Function;
@@ -65,10 +66,11 @@ public Select(SailConnection connection, SparqlFragment queryFragment, String or
if (!sorted && fragment.trim().startsWith("select ")) {
this.query = queryFragment.getNamespacesForSparql() + "\n"
- + StatementMatcher.StableRandomVariableProvider.normalize(fragment);
+ + StatementMatcher.StableRandomVariableProvider.normalize(fragment, List.of(), List.of());
} else {
this.query = queryFragment.getNamespacesForSparql() + "\n" + StatementMatcher.StableRandomVariableProvider
- .normalize("select * where {\n" + fragment + "\n}" + (sorted ? " order by " + orderBy : ""));
+ .normalize("select * where {\n" + fragment + "\n}" + (sorted ? " order by " + orderBy : ""),
+ List.of(), List.of());
}
dataset = PlanNodeHelper.asDefaultGraphDataset(dataGraph);
@@ -85,7 +87,7 @@ public Select(SailConnection connection, String query, Function " + getId())
- .append("\n");
- } else {
- stringBuilder.append(System.identityHashCode(connection) + " -> " + getId()).append("\n");
- }
+// if (connection instanceof MemoryStoreConnection) {
+// stringBuilder
+// .append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> " + getId())
+// .append("\n");
+// } else {
+ stringBuilder.append(System.identityHashCode(connection) + " -> " + getId()).append("\n");
+// }
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SetFilterNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SetFilterNode.java
index f5a8f46c975..ad64b910bac 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SetFilterNode.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SetFilterNode.java
@@ -18,6 +18,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class SetFilterNode implements PlanNode {
@@ -28,8 +29,9 @@ public class SetFilterNode implements PlanNode {
private boolean printed;
private ValidationExecutionLogger validationExecutionLogger;
- public SetFilterNode(Set targetNodeList, PlanNode parent, int index, boolean returnValid) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public SetFilterNode(Set targetNodeList, PlanNode parent, int index, boolean returnValid,
+ ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.targetNodeList = targetNodeList;
this.index = index;
this.returnValid = returnValid;
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ShiftToNodeShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ShiftToNodeShape.java
index 0d0d3fa30b7..e78962815f4 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ShiftToNodeShape.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ShiftToNodeShape.java
@@ -18,6 +18,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -29,8 +30,8 @@ public class ShiftToNodeShape implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public ShiftToNodeShape(PlanNode parent) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public ShiftToNodeShape(PlanNode parent, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
// this.stackTrace = Thread.currentThread().getStackTrace();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ShiftToPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ShiftToPropertyShape.java
index fc2105f738c..0e501473858 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ShiftToPropertyShape.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ShiftToPropertyShape.java
@@ -18,6 +18,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -29,8 +30,8 @@ public class ShiftToPropertyShape implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public ShiftToPropertyShape(PlanNode parent) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public ShiftToPropertyShape(PlanNode parent, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
// this.stackTrace = Thread.currentThread().getStackTrace();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SingleCloseablePlanNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SingleCloseablePlanNode.java
index 285550c060e..3d146736ae0 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SingleCloseablePlanNode.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SingleCloseablePlanNode.java
@@ -17,6 +17,7 @@
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.sail.shacl.ast.Shape;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* A plan node that can only be closed once
@@ -29,8 +30,8 @@ public class SingleCloseablePlanNode implements PlanNode {
private final Shape shape;
boolean receivedLogger = false;
- public SingleCloseablePlanNode(PlanNode parent, Shape shape) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public SingleCloseablePlanNode(PlanNode parent, Shape shape, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.shape = shape;
}
@@ -52,7 +53,7 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
@Override
public String toString() {
- return "SingleCloseablePlanNode{" + "parent=" + parent + '}';
+ return "SingleCloseablePlanNode";
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Sort.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Sort.java
index 70b98311500..202610c1e9c 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Sort.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Sort.java
@@ -20,6 +20,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class Sort implements PlanNode {
@@ -27,8 +28,8 @@ public class Sort implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public Sort(PlanNode parent) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public Sort(PlanNode parent, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
}
@Override
@@ -160,6 +161,6 @@ public boolean requiresSorted() {
@Override
public String toString() {
- return "Sort{" + "parent=" + parent + '}';
+ return "Sort";
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SparqlConstraintSelect.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SparqlConstraintSelect.java
index 0d8dacf53ed..9b244b4bc10 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SparqlConstraintSelect.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/SparqlConstraintSelect.java
@@ -121,29 +121,42 @@ private void calculateNext() {
}
}
- Value value = bindingSet.getValue("value");
+ Value value1 = bindingSet.getValue("value");
+ if (value1 == null) {
+ value1 = nextTarget.getValue();
+ }
+ Value currentValue = value1;
+
Value path = bindingSet.getValue("path");
if (scope == ConstraintComponent.Scope.nodeShape) {
next = nextTarget.addValidationResult(t -> {
- ValidationResult validationResult = new ValidationResult(t.getActiveTarget(), value,
+ ValidationResult validationResult = new ValidationResult(t.getActiveTarget(),
+ currentValue,
shape,
constraintComponent, shape.getSeverity(),
ConstraintComponent.Scope.nodeShape, t.getContexts(),
shape.getContexts());
- validationResult.setPathIri(path);
+ if (path != null) {
+ validationResult.setPathIri(path);
+ }
return validationResult;
});
} else {
- ValidationTuple validationTuple = new ValidationTuple(nextTarget.getActiveTarget(), value,
- scope, true, nextTarget.getContexts());
+
+ ValidationTuple validationTuple = new ValidationTuple(nextTarget.getActiveTarget(),
+ currentValue,
+ scope, currentValue != null, nextTarget.getContexts());
next = ValidationTupleHelper.join(nextTarget, validationTuple).addValidationResult(t -> {
- ValidationResult validationResult = new ValidationResult(t.getActiveTarget(), value,
+ ValidationResult validationResult = new ValidationResult(t.getActiveTarget(),
+ currentValue,
shape,
constraintComponent, shape.getSeverity(),
ConstraintComponent.Scope.propertyShape, t.getContexts(),
shape.getContexts());
- validationResult.setPathIri(path);
+ if (path != null) {
+ validationResult.setPathIri(path);
+ }
return validationResult;
});
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TargetChainPopper.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TargetChainPopper.java
index a27e447388c..d15987ab2ad 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TargetChainPopper.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TargetChainPopper.java
@@ -18,6 +18,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* Pops the last target off of the target chain and into the value.
@@ -34,8 +35,8 @@ public class TargetChainPopper implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public TargetChainPopper(PlanNode parent) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public TargetChainPopper(PlanNode parent, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
// this.stackTrace = Thread.currentThread().getStackTrace();
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TrimToTarget.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TrimToTarget.java
index ddccd356ff0..6bb77f1d193 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TrimToTarget.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TrimToTarget.java
@@ -15,6 +15,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class TrimToTarget implements PlanNode {
@@ -25,8 +26,8 @@ public class TrimToTarget implements PlanNode {
boolean keepPath = false;
- public TrimToTarget(PlanNode parent) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public TrimToTarget(PlanNode parent, ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
// this.stackTrace = Thread.currentThread().getStackTrace();
}
@@ -123,8 +124,7 @@ public int hashCode() {
@Override
public String toString() {
return "TrimToTarget{" +
- "parent=" + parent +
- ", keepPath=" + keepPath +
+ "keepPath=" + keepPath +
'}';
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TupleMapper.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TupleMapper.java
index c407b21431a..f9f3e0bfb92 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TupleMapper.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/TupleMapper.java
@@ -16,6 +16,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class TupleMapper implements PlanNode {
PlanNode parent;
@@ -23,8 +24,9 @@ public class TupleMapper implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public TupleMapper(PlanNode parent, Function function) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public TupleMapper(PlanNode parent, Function function,
+ ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.function = function;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/UnionNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/UnionNode.java
index a130e9c8729..ab21b5dc358 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/UnionNode.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/UnionNode.java
@@ -18,6 +18,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -25,26 +26,28 @@
public class UnionNode implements PlanNode {
private final HashSet nodesSet;
+ private final ConnectionsGroup connectionsGroup;
private StackTraceElement[] stackTrace;
private final PlanNode[] nodes;
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- private UnionNode(PlanNode... nodes) {
+ private UnionNode(ConnectionsGroup connectionsGroup, PlanNode... nodes) {
this.nodes = nodes;
this.nodesSet = new HashSet<>(Arrays.asList(nodes));
+ this.connectionsGroup = connectionsGroup;
// this.stackTrace = Thread.currentThread().getStackTrace();
}
- public static PlanNode getInstance(PlanNode... nodes) {
+ public static PlanNode getInstance(ConnectionsGroup connectionsGroup, PlanNode... nodes) {
PlanNode[] planNodes = Arrays.stream(nodes).filter(n -> !(n.isGuaranteedEmpty())).flatMap(n -> {
if (n instanceof UnionNode) {
return Arrays.stream(((UnionNode) n).nodes);
}
return Stream.of(n);
- }).map(n -> PlanNodeHelper.handleSorting(true, n)).toArray(PlanNode[]::new);
+ }).map(n -> PlanNodeHelper.handleSorting(true, n, connectionsGroup)).toArray(PlanNode[]::new);
if (planNodes.length == 1) {
return planNodes[0];
@@ -53,17 +56,17 @@ public static PlanNode getInstance(PlanNode... nodes) {
return EmptyNode.getInstance();
}
- return new UnionNode(planNodes);
+ return new UnionNode(connectionsGroup, planNodes);
}
- public static PlanNode getInstanceDedupe(PlanNode... nodes) {
+ public static PlanNode getInstanceDedupe(ConnectionsGroup connectionsGroup, PlanNode... nodes) {
PlanNode[] planNodes = Arrays.stream(nodes).filter(n -> !(n.isGuaranteedEmpty())).distinct().flatMap(n -> {
if (n instanceof UnionNode) {
return Arrays.stream(((UnionNode) n).nodes);
}
return Stream.of(n);
- }).map(n -> PlanNodeHelper.handleSorting(true, n)).toArray(PlanNode[]::new);
+ }).map(n -> PlanNodeHelper.handleSorting(true, n, connectionsGroup)).toArray(PlanNode[]::new);
if (planNodes.length == 1) {
return planNodes[0];
@@ -72,7 +75,7 @@ public static PlanNode getInstanceDedupe(PlanNode... nodes) {
return EmptyNode.getInstance();
}
- return new UnionNode(planNodes);
+ return new UnionNode(connectionsGroup, planNodes);
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Unique.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Unique.java
index 4ba1984e1e6..1a0eb2d73b1 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Unique.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/Unique.java
@@ -24,6 +24,7 @@
import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.ConstraintComponent;
import org.eclipse.rdf4j.sail.shacl.wrapper.data.CloseablePeakableIteration;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,9 +40,9 @@ public class Unique implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- private Unique(PlanNode parent, boolean compress) {
+ private Unique(PlanNode parent, boolean compress, ConnectionsGroup connectionsGroup) {
// this.stackTrace = Thread.currentThread().getStackTrace();
- PlanNode tempParent = PlanNodeHelper.handleSorting(this, parent);
+ PlanNode tempParent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
if (tempParent instanceof Unique) {
Unique parentUnique = ((Unique) tempParent);
@@ -57,7 +58,7 @@ private Unique(PlanNode parent, boolean compress) {
this.compress = compress;
}
- public static PlanNode getInstance(PlanNode parent, boolean compress) {
+ public static PlanNode getInstance(PlanNode parent, boolean compress, ConnectionsGroup connectionsGroup) {
if (parent.isGuaranteedEmpty()) {
return parent;
}
@@ -66,7 +67,7 @@ public static PlanNode getInstance(PlanNode parent, boolean compress) {
return parent;
}
- return new Unique(parent, compress);
+ return new Unique(parent, compress, connectionsGroup);
}
@Override
@@ -258,7 +259,6 @@ public int hashCode() {
public String toString() {
return "Unique{" +
"compress=" + compress +
- ", parent=" + parent +
'}';
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/UnorderedSelect.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/UnorderedSelect.java
index 78bc577697f..01b932c026e 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/UnorderedSelect.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/UnorderedSelect.java
@@ -124,13 +124,13 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
// added/removed connections are always newly minted per plan node, so we instead need to compare the underlying
// sail
- if (connection instanceof MemoryStoreConnection) {
- stringBuilder
- .append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> " + getId())
- .append("\n");
- } else {
- stringBuilder.append(System.identityHashCode(connection) + " -> " + getId()).append("\n");
- }
+// if (connection instanceof MemoryStoreConnection) {
+// stringBuilder
+// .append(System.identityHashCode(((MemoryStoreConnection) connection).getSail()) + " -> " + getId())
+// .append("\n");
+// } else {
+ stringBuilder.append(System.identityHashCode(connection) + " -> " + getId()).append("\n");
+// }
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValidationReportNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValidationReportNode.java
index 9810d2df145..21d4edf2a09 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValidationReportNode.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValidationReportNode.java
@@ -17,6 +17,7 @@
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.sail.shacl.results.ValidationResult;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
public class ValidationReportNode implements PlanNode {
@@ -25,8 +26,9 @@ public class ValidationReportNode implements PlanNode {
private boolean printed = false;
private ValidationExecutionLogger validationExecutionLogger;
- public ValidationReportNode(PlanNode parent, Function validationResultFunction) {
- this.parent = PlanNodeHelper.handleSorting(this, parent);
+ public ValidationReportNode(PlanNode parent, Function validationResultFunction,
+ ConnectionsGroup connectionsGroup) {
+ this.parent = PlanNodeHelper.handleSorting(this, parent, connectionsGroup);
this.validationResultFunction = validationResultFunction;
}
@@ -79,6 +81,9 @@ public void getPlanAsGraphvizDot(StringBuilder stringBuilder) {
.append(StringEscapeUtils.escapeJava(this.toString()))
.append("\"];")
.append("\n");
+ stringBuilder.append(parent.getId() + " -> " + getId()).append("\n");
+
+ parent.getPlanAsGraphvizDot(stringBuilder);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValidationTuple.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValidationTuple.java
index 3bad814ab15..f208b619303 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValidationTuple.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValidationTuple.java
@@ -323,6 +323,7 @@ public List getTargetChain(boolean includePropertyShapeValues) {
}
public ValidationTuple setValue(Value value) {
+ assert value != null;
if (value.equals(getValue())) {
return this;
}
@@ -493,7 +494,9 @@ public ValidationTuple join(ValidationTuple right) {
ValidationTuple validationTuple = new ValidationTuple(validationResults, chain, scope,
propertyShapeScopeWithValue, compressedTuples, contexts);
if (scope == ConstraintComponent.Scope.propertyShape) {
- validationTuple = validationTuple.setValue(right.getValue());
+ if (right.hasValue()) {
+ validationTuple = validationTuple.setValue(right.getValue());
+ }
}
for (ValidationResult validationResult : right.getValidationResult()) {
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValueInFilter.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValueInFilter.java
index b73906c7a5b..dff0a687f15 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValueInFilter.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/ValueInFilter.java
@@ -16,6 +16,7 @@
import java.util.Set;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
/**
* @author Håvard Ottestad
@@ -24,8 +25,8 @@ public class ValueInFilter extends FilterPlanNode {
private final Set valueSet;
- public ValueInFilter(PlanNode parent, Set valueSet) {
- super(parent);
+ public ValueInFilter(PlanNode parent, Set valueSet, ConnectionsGroup connectionsGroup) {
+ super(parent, connectionsGroup);
this.valueSet = valueSet;
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/sort-after.txt b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/sort-after.txt
new file mode 100644
index 00000000000..c089cefe02e
--- /dev/null
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/sort-after.txt
@@ -0,0 +1,896 @@
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:129)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/sort-before.txt b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/sort-before.txt
new file mode 100644
index 00000000000..6ae9ee9f5c3
--- /dev/null
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/sort-before.txt
@@ -0,0 +1,896 @@
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.targets.TargetClass.getTargetFilter(TargetClass.java:128)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
+org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeHelper.handleSorting(PlanNodeHelper.java:37)
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/DashAllObjects.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/DashAllObjects.java
index 51f0634a488..8decbb793ec 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/DashAllObjects.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/DashAllObjects.java
@@ -57,21 +57,22 @@ public void toModel(Resource subject, IRI predicate, Model model, Set
@Override
public PlanNode getAdded(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
ConstraintComponent.Scope scope) {
- return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope);
+ return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope, connectionsGroup);
}
private PlanNode getAddedRemovedInner(SailConnection connection, Resource[] dataGraph,
- ConstraintComponent.Scope scope) {
+ ConstraintComponent.Scope scope, ConnectionsGroup connectionsGroup) {
return Unique.getInstance(new UnorderedSelect(connection, null,
- null, null, dataGraph, UnorderedSelect.Mapper.ObjectScopedMapper.getFunction(scope), null), false);
+ null, null, dataGraph, UnorderedSelect.Mapper.ObjectScopedMapper.getFunction(scope), null), false,
+ connectionsGroup);
}
@Override
public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
PlanNode parent) {
- return new FilterTargetIsObject(connectionsGroup.getBaseConnection(), dataGraph, parent)
+ return new FilterTargetIsObject(connectionsGroup.getBaseConnection(), dataGraph, parent, connectionsGroup)
.getTrueNode(UnBufferedPlanNode.class);
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/DashAllSubjects.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/DashAllSubjects.java
index b55de730338..292e2176188 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/DashAllSubjects.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/DashAllSubjects.java
@@ -55,21 +55,22 @@ public void toModel(Resource subject, IRI predicate, Model model, Set
@Override
public PlanNode getAdded(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
ConstraintComponent.Scope scope) {
- return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope);
+ return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope, connectionsGroup);
}
private PlanNode getAddedRemovedInner(SailConnection connection, Resource[] dataGraph,
- ConstraintComponent.Scope scope) {
+ ConstraintComponent.Scope scope, ConnectionsGroup connectionsGroup) {
return Unique.getInstance(new UnorderedSelect(connection, null,
- null, null, dataGraph, UnorderedSelect.Mapper.SubjectScopedMapper.getFunction(scope), null), false);
+ null, null, dataGraph, UnorderedSelect.Mapper.SubjectScopedMapper.getFunction(scope), null), false,
+ connectionsGroup);
}
@Override
public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
PlanNode parent) {
- return new FilterTargetIsSubject(connectionsGroup.getBaseConnection(), dataGraph, parent)
+ return new FilterTargetIsSubject(connectionsGroup.getBaseConnection(), dataGraph, parent, connectionsGroup)
.getTrueNode(UnBufferedPlanNode.class);
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java
index 7a68228bc58..eeadb293dc2 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java
@@ -13,6 +13,7 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -115,46 +116,62 @@ public PlanNode extend(PlanNode source, ConnectionsGroup connectionsGroup, Resou
return allTargets;
}
- var vars = getVars();
- if (includePropertyShapeValues) {
- vars = new ArrayList<>(vars);
- vars.add(optional.var);
- }
+ var vars = getVars(includePropertyShapeValues);
List varNames = vars.stream().map(StatementMatcher.Variable::getName).collect(Collectors.toList());
if (varNames.size() == 1) {
PlanNode parent = new TupleMapper(source,
- new ActiveTargetTupleMapper(scope, includePropertyShapeValues, dataGraph));
+ new ActiveTargetTupleMapper(scope, includePropertyShapeValues, dataGraph), connectionsGroup);
if (filter != null) {
parent = filter.apply(parent);
}
return connectionsGroup
- .getCachedNodeFor(getTargetFilter(connectionsGroup, dataGraph, Unique.getInstance(parent, false)));
+ .getCachedNodeFor(getTargetFilter(connectionsGroup, dataGraph,
+ Unique.getInstance(parent, false, connectionsGroup)));
} else {
SparqlFragment query = getQueryFragment(includePropertyShapeValues);
PlanNode parent = new BindSelect(connectionsGroup.getBaseConnection(), dataGraph, query, vars, source,
varNames, scope,
- 1000, direction, includePropertyShapeValues);
+ 1000, direction, includePropertyShapeValues, connectionsGroup);
if (filter != null) {
parent = connectionsGroup.getCachedNodeFor(parent);
parent = filter.apply(parent);
- parent = Unique.getInstance(parent, true);
+ parent = Unique.getInstance(parent, true, connectionsGroup);
return parent;
} else {
return connectionsGroup.getCachedNodeFor(
- Unique.getInstance(parent, true));
+ Unique.getInstance(parent, true, connectionsGroup));
}
}
}
- private List> getVars() {
+ private List> getVars(boolean optional) {
+ int chainSize = chain.size();
+ if (chainSize == 1) {
+ if (optional) {
+ return List.of(chain.getFirst().var, this.optional.var);
+ } else {
+ return List.of(chain.getFirst().var);
+ }
+ } else if (chainSize == 2) {
+ if (optional) {
+ return List.of(chain.getFirst().var, chain.getLast().var, this.optional.var);
+ } else {
+ return List.of(chain.getFirst().var, chain.getLast().var);
+ }
+ }
+
+ if (optional) {
+ return Stream.concat(chain.stream(), Stream.of(this.optional)).map(t -> t.var).collect(Collectors.toList());
+ }
+
return chain.stream().map(t -> t.var).collect(Collectors.toList());
}
@@ -222,7 +239,7 @@ public boolean couldMatch(ConnectionsGroup connectionsGroup, Resource[] dataGrap
public PlanNode getAllTargets(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
ConstraintComponent.Scope scope) {
- return new AllTargetsPlanNode(connectionsGroup.getBaseConnection(), dataGraph, chain, getVars(), scope);
+ return new AllTargetsPlanNode(connectionsGroup.getBaseConnection(), dataGraph, chain, getVars(false), scope);
}
public PlanNode getPlanNode(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
@@ -288,7 +305,7 @@ public PlanNode getPlanNode(ConnectionsGroup connectionsGroup, Resource[] dataGr
statementMatchersRemoval,
optional,
fragment,
- getVars(),
+ getVars(false),
scope,
false);
} else {
@@ -299,21 +316,31 @@ public PlanNode getPlanNode(ConnectionsGroup connectionsGroup, Resource[] dataGr
null,
null,
fragment,
- getVars(),
+ getVars(false),
scope,
false);
}
} else {
targetsPlanNode = new AllTargetsPlanNode(connectionsGroup.getBaseConnection(), dataGraph, chain,
- getVars(), scope);
+ getVars(false), scope);
}
if (filter != null) {
- return connectionsGroup.getCachedNodeFor(Unique.getInstance(filter.apply(targetsPlanNode), true));
+ if (chain.size() > 1) {
+ return connectionsGroup.getCachedNodeFor(
+ Unique.getInstance(filter.apply(targetsPlanNode), true, connectionsGroup));
+ } else {
+ return connectionsGroup.getCachedNodeFor(filter.apply(targetsPlanNode));
+ }
} else {
- return connectionsGroup.getCachedNodeFor(Unique.getInstance(targetsPlanNode, true));
+ if (chain.size() > 1) {
+ return connectionsGroup
+ .getCachedNodeFor(Unique.getInstance(targetsPlanNode, true, connectionsGroup));
+ } else {
+ return connectionsGroup.getCachedNodeFor(targetsPlanNode);
+ }
}
}
@@ -345,7 +372,7 @@ public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] da
// TODO: this is a slow way to solve this problem! We should use bulk operations.
return new ExternalFilterByQuery(connectionsGroup.getBaseConnection(), dataGraph, parent, sparqlFragment,
last.var,
- ValidationTuple::getActiveTarget, null)
+ ValidationTuple::getActiveTarget, null, connectionsGroup)
.getTrueNode(UnBufferedPlanNode.class);
}
@@ -401,6 +428,10 @@ public Variable getOptionalVar() {
return Objects.requireNonNull(optional, "Optional was null").var;
}
+ public int size() {
+ return chain.size();
+ }
+
public enum Extend {
left,
right
@@ -474,13 +505,9 @@ public Stream getRoot(ConnectionsGroup connectionsGroup, R
if (target instanceof Path) {
Path path = (Path) target;
assert !(path instanceof InversePath);
- Stream root = queryFragment.getRoot(connectionsGroup, dataGraph, path,
+ return queryFragment.getRoot(connectionsGroup, dataGraph, path,
currentStatementMatcher,
List.of(currentStatement));
-
- List collect = root.collect(Collectors.toList());
-
- return collect.stream();
}
throw new UnsupportedOperationException();
@@ -512,6 +539,14 @@ public StatementMatcher getStatementMatcher() {
public boolean hasStatements() {
return !statements.isEmpty();
}
+
+ @Override
+ public String toString() {
+ return "StatementsAndMatcher{" +
+ "statements=" + Arrays.toString(statements.toArray()) +
+ ", statementMatcher=" + statementMatcher +
+ '}';
+ }
}
static class ActiveTargetTupleMapper implements Function {
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/RSXTargetShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/RSXTargetShape.java
index 6965f476374..a8dd7c92920 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/RSXTargetShape.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/RSXTargetShape.java
@@ -96,7 +96,7 @@ private PlanNode getAddedRemovedInner(ConnectionsGroup connectionsGroup, Resourc
sparqlFragment,
vars,
scope,
- false), false);
+ false), false, connectionsGroup);
}
@@ -113,7 +113,7 @@ public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] da
// TODO: this is a slow way to solve this problem! We should use bulk operations.
return new ExternalFilterByQuery(connectionsGroup.getBaseConnection(), dataGraph, parent, sparqlFragment,
variable,
- ValidationTuple::getActiveTarget, null).getTrueNode(UnBufferedPlanNode.class);
+ ValidationTuple::getActiveTarget, null, connectionsGroup).getTrueNode(UnBufferedPlanNode.class);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/SparqlTarget.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/SparqlTarget.java
index da22b013fdb..d066d112cdc 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/SparqlTarget.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/SparqlTarget.java
@@ -114,7 +114,7 @@ public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] da
// TODO: this is a slow way to solve this problem! We should use bulk operations.
return new ExternalFilterByQuery(connectionsGroup.getBaseConnection(), dataGraph, parent, sparqlFragment,
StatementMatcher.Variable.THIS,
- ValidationTuple::getActiveTarget, null).getTrueNode(UnBufferedPlanNode.class);
+ ValidationTuple::getActiveTarget, null, connectionsGroup).getTrueNode(UnBufferedPlanNode.class);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetChainRetriever.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetChainRetriever.java
index eaa5af256e1..767b7a7a377 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetChainRetriever.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetChainRetriever.java
@@ -14,6 +14,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
@@ -80,8 +81,10 @@ public class TargetChainRetriever implements PlanNode {
private final EffectiveTarget.EffectiveTargetFragment removedStatementTarget;
private final boolean hasValue;
private final Set varNamesInQueryFragment;
+ private final Set originalStatementMatchers;
private StackTraceElement[] stackTrace;
+
private ValidationExecutionLogger validationExecutionLogger;
public TargetChainRetriever(ConnectionsGroup connectionsGroup,
@@ -94,7 +97,19 @@ public TargetChainRetriever(ConnectionsGroup connectionsGroup,
this.varNames = vars.stream().map(StatementMatcher.Variable::getName).collect(Collectors.toSet());
assert !this.varNames.isEmpty();
this.dataset = PlanNodeHelper.asDefaultGraphDataset(this.dataGraph);
+
+ var union = statementMatchers;
+ if (removedStatementMatchers != null) {
+ union = new ArrayList<>(statementMatchers);
+ union.addAll(removedStatementMatchers);
+ }
+
+ this.queryFragment = queryFragment.getNamespacesForSparql()
+ + StatementMatcher.StableRandomVariableProvider.normalize(queryFragment.getFragment(), vars, union);
+
+ this.originalStatementMatchers = new HashSet<>(statementMatchers);
this.statementMatchers = StatementMatcher.reduce(statementMatchers);
+ assert originalStatementMatchers.containsAll(this.statementMatchers);
this.scope = scope;
@@ -103,11 +118,6 @@ public TargetChainRetriever(ConnectionsGroup connectionsGroup,
.reduce((a, b) -> a + " " + b)
.orElseThrow(IllegalStateException::new);
- this.queryFragment = queryFragment.getNamespacesForSparql()
- + StatementMatcher.StableRandomVariableProvider.normalize(queryFragment.getFragment());
-
-// this.stackTrace = Thread.currentThread().getStackTrace();
-
this.queryParserFactory = QueryParserRegistry.getInstance()
.get(QueryLanguage.SPARQL)
.get();
@@ -123,12 +133,17 @@ public TargetChainRetriever(ConnectionsGroup connectionsGroup,
? StatementMatcher.reduce(removedStatementMatchers)
: Collections.emptyList();
+ assert removedStatementMatchers == null || removedStatementMatchers.containsAll(this.removedStatementMatchers);
+
this.removedStatementTarget = removedStatementTarget;
this.hasValue = hasValue;
assert scope == ConstraintComponent.Scope.propertyShape || !this.hasValue;
+ if (logger.isDebugEnabled()) {
+ this.stackTrace = Thread.currentThread().getStackTrace();
+ }
}
@Override
@@ -197,12 +212,19 @@ public void calculateNextStatementMatcher() {
removedStatement = true;
}
- this.sparqlValuesDecl = currentStatementMatcher.getSparqlValuesDecl(varNames, removedStatement,
+ // we need to add the inherited names if we are going to chase the root of the
+ // currentStatementMatcher later
+ boolean addInherited = chaseRoot();
+
+ this.sparqlValuesDecl = currentStatementMatcher.getSparqlValuesDecl(varNames, addInherited,
varNamesInQueryFragment);
- this.currentVarNames = currentStatementMatcher.getVarNames(varNames, removedStatement,
+ this.currentVarNames = currentStatementMatcher.getVarNames(varNames, addInherited,
varNamesInQueryFragment);
- assert !currentVarNames.isEmpty() : "currentVarNames is empty!";
+ if (currentVarNames.isEmpty()) {
+ logger.error("currentVarNames should not be empty!");
+ throw new IllegalStateException("currentVarNames should not be empty!");
+ }
statements = connection.getStatements(
currentStatementMatcher.getSubjectValue(),
@@ -215,6 +237,11 @@ public void calculateNextStatementMatcher() {
}
+ private boolean chaseRoot() {
+ return removedStatementTarget != null && removedStatement
+ && !originalStatementMatchers.contains(currentStatementMatcher);
+ }
+
private void calculateNextResult() {
if (next != null) {
return;
@@ -280,18 +307,21 @@ private void calculateNextResult() {
}
- private List readStatementsInBulk(Set varNames) {
+ private List readStatementsInBulk(Set variableNames) {
bulk.clear();
while (bulk.size() < BULK_SIZE && statements.hasNext()) {
Statement next = statements.next();
Stream rootStatements = Stream
.of(new EffectiveTarget.StatementsAndMatcher(List.of(next), currentStatementMatcher));
- if (removedStatement && removedStatementTarget != null) {
+ if (chaseRoot()) {
+ // we only need to find the root if the currentStatementMatcher doesn't match anything in the
+ // query
Stream root = removedStatementTarget.getRoot(
connectionsGroup,
dataGraph, currentStatementMatcher,
next);
+
if (root != null) {
rootStatements = root;
}
@@ -306,7 +336,7 @@ private List readStatementsInBulk(Set varNames) {
return statementsAndMatcher.getStatements()
.stream()
.map(temp -> {
- Binding[] bindings = new Binding[varNames.size()];
+ Binding[] bindings = new Binding[variableNames.size()];
int j = 0;
if (newCurrentStatementMatcher.getSubjectValue() == null
@@ -337,7 +367,7 @@ private List readStatementsInBulk(Set varNames) {
bindings[0].getValue());
} else {
- return new SimpleBindingSet(varNames, bindings);
+ return new SimpleBindingSet(variableNames, bindings);
}
});
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetClass.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetClass.java
index 3ad450e7901..0036591c91b 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetClass.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetClass.java
@@ -56,16 +56,17 @@ public IRI getPredicate() {
@Override
public PlanNode getAdded(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
ConstraintComponent.Scope scope) {
- return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope);
+ return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope, connectionsGroup);
}
private PlanNode getAddedRemovedInner(SailConnection connection, Resource[] dataGraph,
- ConstraintComponent.Scope scope) {
+ ConstraintComponent.Scope scope, ConnectionsGroup connectionsGroup) {
PlanNode planNode;
if (targetClass.size() == 1) {
Resource clazz = targetClass.stream().findAny().get();
planNode = new UnorderedSelect(connection, null, RDF.TYPE, clazz,
dataGraph, UnorderedSelect.Mapper.SubjectScopedMapper.getFunction(scope), null);
+// return planNode;
} else {
planNode = new Select(connection,
SparqlFragment.bgp(Set.of(),
@@ -73,7 +74,7 @@ private PlanNode getAddedRemovedInner(SailConnection connection, Resource[] data
"?a", b -> new ValidationTuple(b.getValue("a"), scope, false, dataGraph), dataGraph);
}
- return Unique.getInstance(planNode, false);
+ return Unique.getInstance(planNode, false, connectionsGroup);
}
String getQueryFragment(String subjectVariable, String objectVariable,
@@ -96,7 +97,7 @@ String getQueryFragment(String subjectVariable, String objectVariable,
"{",
"BIND(rdf:type as " + stableRandomVariableProvider.next().asSparqlVariable() + ")",
"BIND(" + r + " as " + objectVariable + ")",
- "" + subjectVariable + " " + stableRandomVariableProvider.current().asSparqlVariable()
+ subjectVariable + " " + stableRandomVariableProvider.current().asSparqlVariable()
+ objectVariable + ".",
"}"
)
@@ -111,24 +112,27 @@ public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] da
PlanNode parent) {
if (connectionsGroup.hasAddedStatements()) {
- BufferedSplitter bufferedSplitter = new BufferedSplitter(parent);
+ BufferedSplitter bufferedSplitter = BufferedSplitter.getInstance(parent);
FilterByPredicateObject typeFoundInAdded = new FilterByPredicateObject(
connectionsGroup.getAddedStatements(), dataGraph, RDF.TYPE, targetClass,
- bufferedSplitter.getPlanNode(), true, FilterByPredicateObject.FilterOn.activeTarget, false);
+ bufferedSplitter.getPlanNode(), true, FilterByPredicateObject.FilterOn.activeTarget, false,
+ connectionsGroup);
FilterByPredicateObject typeNotFoundInAdded = new FilterByPredicateObject(
connectionsGroup.getAddedStatements(), dataGraph, RDF.TYPE, targetClass,
- bufferedSplitter.getPlanNode(), false, FilterByPredicateObject.FilterOn.activeTarget, false);
+ bufferedSplitter.getPlanNode(), false, FilterByPredicateObject.FilterOn.activeTarget, false,
+ connectionsGroup);
FilterByPredicateObject filterAgainstBaseConnection = new FilterByPredicateObject(
connectionsGroup.getBaseConnection(), dataGraph, RDF.TYPE, targetClass, typeNotFoundInAdded, true,
- FilterByPredicateObject.FilterOn.activeTarget, true);
+ FilterByPredicateObject.FilterOn.activeTarget, true, connectionsGroup);
- return new Sort(UnionNode.getInstance(typeFoundInAdded, filterAgainstBaseConnection));
+ return new Sort(UnionNode.getInstance(connectionsGroup, typeFoundInAdded, filterAgainstBaseConnection),
+ connectionsGroup);
} else {
return new FilterByPredicateObject(connectionsGroup.getBaseConnection(), dataGraph, RDF.TYPE,
- targetClass, parent, true, FilterByPredicateObject.FilterOn.activeTarget, true);
+ targetClass, parent, true, FilterByPredicateObject.FilterOn.activeTarget, true, connectionsGroup);
}
}
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetNode.java
index 34c1045258a..2bb4ad9a5f1 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetNode.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetNode.java
@@ -57,7 +57,7 @@ public PlanNode getAdded(ConnectionsGroup connectionsGroup, Resource[] dataGraph
@Override
public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
PlanNode parent) {
- return new SetFilterNode(targetNodes, parent, 0, true);
+ return new SetFilterNode(targetNodes, parent, 0, true, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetObjectsOf.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetObjectsOf.java
index 3d7504ba77a..2633682efce 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetObjectsOf.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetObjectsOf.java
@@ -59,26 +59,26 @@ public void toModel(Resource subject, IRI predicate, Model model, Set
@Override
public PlanNode getAdded(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
ConstraintComponent.Scope scope) {
- return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope);
+ return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope, connectionsGroup);
}
private PlanNode getAddedRemovedInner(SailConnection connection, Resource[] dataGraph,
- ConstraintComponent.Scope scope) {
+ ConstraintComponent.Scope scope, ConnectionsGroup connectionsGroup) {
PlanNode planNode = targetObjectsOf.stream()
.map(predicate -> (PlanNode) new UnorderedSelect(connection, null,
predicate, null, dataGraph, UnorderedSelect.Mapper.ObjectScopedMapper.getFunction(scope), null))
- .reduce(UnionNode::getInstance)
+ .reduce((nodes, nodes2) -> UnionNode.getInstance(connectionsGroup, nodes, nodes2))
.orElse(EmptyNode.getInstance());
- return Unique.getInstance(planNode, false);
+ return Unique.getInstance(planNode, false, connectionsGroup);
}
@Override
public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
PlanNode parent) {
return new FilterByPredicate(connectionsGroup.getBaseConnection(), targetObjectsOf, parent,
- FilterByPredicate.On.Object, dataGraph);
+ FilterByPredicate.On.Object, dataGraph, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetSubjectsOf.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetSubjectsOf.java
index 72111f319c6..2d5e866f81f 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetSubjectsOf.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetSubjectsOf.java
@@ -59,27 +59,27 @@ public void toModel(Resource subject, IRI predicate, Model model, Set
@Override
public PlanNode getAdded(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
ConstraintComponent.Scope scope) {
- return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope);
+ return getAddedRemovedInner(connectionsGroup.getAddedStatements(), dataGraph, scope, connectionsGroup);
}
private PlanNode getAddedRemovedInner(SailConnection connection, Resource[] dataGraph,
- ConstraintComponent.Scope scope) {
+ ConstraintComponent.Scope scope, ConnectionsGroup connectionsGroup) {
PlanNode planNode = targetSubjectsOf.stream()
.map(predicate -> (PlanNode) new UnorderedSelect(connection, null,
predicate, null, dataGraph, UnorderedSelect.Mapper.SubjectScopedMapper.getFunction(scope),
null))
- .reduce(UnionNode::getInstance)
+ .reduce((nodes, nodes2) -> UnionNode.getInstance(connectionsGroup, nodes, nodes2))
.orElse(EmptyNode.getInstance());
- return Unique.getInstance(planNode, false);
+ return Unique.getInstance(planNode, false, connectionsGroup);
}
@Override
public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
PlanNode parent) {
return new FilterByPredicate(connectionsGroup.getBaseConnection(), targetSubjectsOf, parent,
- FilterByPredicate.On.Subject, dataGraph);
+ FilterByPredicate.On.Subject, dataGraph, connectionsGroup);
}
@Override
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/results/ValidationResult.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/results/ValidationResult.java
index faf328d7917..600a8cd6ee8 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/results/ValidationResult.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/results/ValidationResult.java
@@ -77,18 +77,16 @@ public ValidationResult(Value focusNode, Value value, Shape shape,
this.shape = shape;
if (sourceConstraintComponent.producesValidationResultValue()) {
- assert value != null;
+ assert !sourceConstraintComponent.alwaysProducesValidationResultValue() || value != null;
// value could be null if assertions are disabled
// noinspection ConstantValue
- if (value == null) {
+ if (value == null && sourceConstraintComponent.alwaysProducesValidationResultValue()) {
logger.error(
"Source constraint component {} was expected to produce a value, but value is null! Shape: {}",
sourceConstraintComponent, shape);
}
- // value could be null if assertions are disabled
- // noinspection OptionalOfNullableMisuse
this.value = Optional.ofNullable(value);
} else {
assert scope != ConstraintComponent.Scope.propertyShape || value == null;
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/wrapper/data/ConnectionsGroup.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/wrapper/data/ConnectionsGroup.java
index 55ee9b26455..38461cb1edf 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/wrapper/data/ConnectionsGroup.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/wrapper/data/ConnectionsGroup.java
@@ -130,7 +130,7 @@ public PlanNode getCachedNodeFor(PlanNode planNode) {
BufferedSplitter bufferedSplitter = nodeCache.computeIfAbsent(planNode, parent -> {
matchedCache[0] = false;
- return new BufferedSplitter(parent, true);
+ return BufferedSplitter.getInstance(parent);
});
logger.debug("Found in cache: {} {} - {} : {}", matchedCache[0] ? " TRUE" : "FALSE",
@@ -138,7 +138,7 @@ public PlanNode getCachedNodeFor(PlanNode planNode) {
return bufferedSplitter.getPlanNode();
} else {
- return nodeCache.computeIfAbsent(planNode, BufferedSplitter::new).getPlanNode();
+ return nodeCache.computeIfAbsent(planNode, BufferedSplitter::getInstance).getPlanNode();
}
}
diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java
index 94a2667d6db..f62d336424d 100644
--- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java
+++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java
@@ -11,6 +11,7 @@
package org.eclipse.rdf4j.sail.shacl;
+import static org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import java.io.File;
@@ -83,6 +84,7 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.Isolated;
import org.junit.jupiter.params.provider.Arguments;
import org.slf4j.Logger;
@@ -115,7 +117,7 @@ abstract public class AbstractShaclTest {
"test-cases/path/zeroOrOnePath"
);
- public static final Set ISOLATION_LEVELS = Set.of(
+ public static final List ISOLATION_LEVELS = List.of(
IsolationLevels.NONE,
IsolationLevels.SNAPSHOT,
IsolationLevels.SERIALIZABLE
@@ -222,7 +224,7 @@ private static Stream findTestCases(String testCase, ExpectedResult ba
if (files != null) {
Optional initialData = Arrays.stream(files)
.map(File::getName)
- .filter(name -> name.equals("initialData.ttl"))
+ .filter(name -> name.equals("initialData.trig"))
.findAny();
List queries = Arrays.stream(files)
.filter(f -> f.getName().endsWith(".rq"))
@@ -311,7 +313,7 @@ static void afterAll() throws IllegalAccessException {
}
@AfterEach
- void tearDown() {
+ void afterEach() {
fullLogging = false;
}
@@ -553,16 +555,21 @@ void referenceImplementationTestCaseValidation(TestCase testCase) {
return;
}
- // uses rsx:nodeShape
+ // uses rsx:targetShape
if (testCase.testCasePath.startsWith("test-cases/qualifiedShape/complex/")) {
return;
}
- // uses rsx:nodeShape
+ // uses rsx:targetShape
if (testCase.testCasePath.startsWith("test-cases/complex/targetShapeAndQualifiedShape/")) {
return;
}
+ // uses rsx:targetShape
+ if (testCase.testCasePath.startsWith("test-cases/path/sequencePathTargetShape")) {
+ return;
+ }
+
// sh:shapesGraph
if (testCase.testCasePath.startsWith("test-cases/datatype/simpleNamedGraph/")) {
return;
@@ -594,6 +601,12 @@ void referenceImplementationTestCaseValidation(TestCase testCase) {
return;
}
+ // the TopBraid SHACL API doesn't agree with other implementations on how multiple paths to the same target
+ // should work
+ if (testCase.testCasePath.startsWith("test-cases/nodeKind/simpleCompress/")) {
+ return;
+ }
+
printTestCase(testCase);
Dataset shaclDataset = DatasetFactory.create();
@@ -1061,7 +1074,13 @@ void runParsingTest(TestCase testCase) {
return;
}
- SailRepository shaclRepository = getShaclSail(testCase);
+ SailRepository shaclRepository;
+ try {
+ shaclRepository = getShaclSail(testCase);
+ } catch (Exception e) {
+ System.err.println(testCase.getTestCasePath() + "shacl.trig");
+ throw e;
+ }
try {
List shapes = ((ShaclSail) shaclRepository.getSail()).getCachedShapes()
diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/EqualsJoinTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/EqualsJoinTest.java
index ef00e2961f6..26775365afa 100644
--- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/EqualsJoinTest.java
+++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/EqualsJoinTest.java
@@ -41,7 +41,7 @@ public void testSimple01() {
PlanNode left = new MockInputPlanNode(List.of("a"));
PlanNode right = new MockInputPlanNode(List.of("a"), List.of("b"));
- EqualsJoin equalsJoin = new EqualsJoin(left, right, false);
+ EqualsJoin equalsJoin = new EqualsJoin(left, right, false, null);
List tuples = new MockConsumePlanNode(equalsJoin).asList();
@@ -55,7 +55,7 @@ public void testSimple02() {
PlanNode left = new MockInputPlanNode(List.of("a"), List.of("c"));
PlanNode right = new MockInputPlanNode(List.of("a"), List.of("b"), List.of("c"));
- EqualsJoin equalsJoin = new EqualsJoin(left, right, false);
+ EqualsJoin equalsJoin = new EqualsJoin(left, right, false, null);
List tuples = new MockConsumePlanNode(equalsJoin).asList();
@@ -69,7 +69,7 @@ public void testSimple03() {
PlanNode right = new MockInputPlanNode(List.of("a"), List.of("c"));
PlanNode left = new MockInputPlanNode(List.of("a"), List.of("b"), List.of("c"));
- EqualsJoin equalsJoin = new EqualsJoin(left, right, false);
+ EqualsJoin equalsJoin = new EqualsJoin(left, right, false, null);
List tuples = new MockConsumePlanNode(equalsJoin).asList();
@@ -83,7 +83,7 @@ public void testSimple04() {
PlanNode left = new MockInputPlanNode(List.of("b"), List.of("c"));
PlanNode right = new MockInputPlanNode(List.of("a"), List.of("d"), List.of("e"));
- EqualsJoin equalsJoin = new EqualsJoin(left, right, false);
+ EqualsJoin equalsJoin = new EqualsJoin(left, right, false, null);
List tuples = new MockConsumePlanNode(equalsJoin).asList();
@@ -97,7 +97,7 @@ public void testSimple05() {
PlanNode left = new MockInputPlanNode(List.of("b"), List.of("c"));
PlanNode right = new MockInputPlanNode(List.of("a"), List.of("d"), List.of("c"));
- EqualsJoin equalsJoin = new EqualsJoin(left, right, false);
+ EqualsJoin equalsJoin = new EqualsJoin(left, right, false, null);
List tuples = new MockConsumePlanNode(equalsJoin).asList();
@@ -113,7 +113,7 @@ public void testSimple06() {
PlanNode right = new MockInputPlanNode(Arrays.asList("a", "1"), Arrays.asList("b", "1"),
Arrays.asList("b", "1"), Arrays.asList("c", "1"));
- EqualsJoin equalsJoin = new EqualsJoin(left, right, true);
+ EqualsJoin equalsJoin = new EqualsJoin(left, right, true, null);
List tuples = new MockConsumePlanNode(equalsJoin).asList();
diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/InnerJoinTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/InnerJoinTest.java
index aeb1324dee5..da8d83be01b 100644
--- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/InnerJoinTest.java
+++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/InnerJoinTest.java
@@ -42,7 +42,7 @@ public void testSimple() {
PlanNode left = new MockInputPlanNode(List.of("a"));
PlanNode right = new MockInputPlanNode(Arrays.asList("a", "b"));
- PlanNode innerJoin = new InnerJoin(left, right).getJoined(BufferedPlanNode.class);
+ PlanNode innerJoin = new InnerJoin(left, right, null).getJoined(BufferedPlanNode.class);
List tuples = new MockConsumePlanNode(innerJoin).asList();
@@ -58,7 +58,7 @@ public void testSimple2() {
PlanNode left = new MockInputPlanNode(List.of("a1"), List.of("a2"));
PlanNode right = new MockInputPlanNode(Arrays.asList("a1", "b"));
- PlanNode innerJoin = new InnerJoin(left, right).getJoined(BufferedPlanNode.class);
+ PlanNode innerJoin = new InnerJoin(left, right, null).getJoined(BufferedPlanNode.class);
List tuples = new MockConsumePlanNode(innerJoin).asList();
@@ -74,7 +74,7 @@ public void testSimple3() {
PlanNode left = new MockInputPlanNode(List.of("a1"), List.of("a2"));
PlanNode right = new MockInputPlanNode(Arrays.asList("a2", "b"));
- PlanNode innerJoin = new InnerJoin(left, right).getJoined(BufferedPlanNode.class);
+ PlanNode innerJoin = new InnerJoin(left, right, null).getJoined(BufferedPlanNode.class);
List