diff --git a/.github/workflows/merge_main_to_develop.yml b/.github/workflows/merge_main_to_develop.yml index d5d3d80d5aa..f4f12b53ba7 100644 --- a/.github/workflows/merge_main_to_develop.yml +++ b/.github/workflows/merge_main_to_develop.yml @@ -17,4 +17,4 @@ jobs: destination_branch: "develop" # If blank, default: main pr_title: "Merge main into develop" pr_body: "Automatically generated PR to keep develop in sync with main.\n\n **USE MERGE COMMIT TO MERGE THIS PR**.\n\nSee [merge_main_to_develop.yml](/eclipse/rdf4j/.github/workflows/merge_main_to_develop.yml)." # Full markdown support, requires pr_title to be set - github_token: ${{ secrets.GITHUB_TOKEN }} + github_token: ${{ github.token }} diff --git a/.gitignore b/.gitignore index 75b520bf014..574d708ce85 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ org.eclipse.dash.licenses-1.0.2.jar e2e/node_modules e2e/playwright-report e2e/test-results +.aider* diff --git a/assembly-descriptors/pom.xml b/assembly-descriptors/pom.xml index 82b0cf3d235..837f7647d0a 100644 --- a/assembly-descriptors/pom.xml +++ b/assembly-descriptors/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-assembly-descriptors RDF4J: Assembly Descriptors diff --git a/assembly/pom.xml b/assembly/pom.xml index 07f9979c812..c5decadbbda 100644 --- a/assembly/pom.xml +++ b/assembly/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-assembly pom diff --git a/bom/pom.xml b/bom/pom.xml index 79916ecc533..e7312671ab1 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-bom pom diff --git a/compliance/elasticsearch/pom.xml b/compliance/elasticsearch/pom.xml index a0098c62770..4684d29c437 100644 --- a/compliance/elasticsearch/pom.xml +++ b/compliance/elasticsearch/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-compliance - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-elasticsearch-compliance RDF4J: Elasticsearch Sail Tests diff --git a/compliance/geosparql/pom.xml b/compliance/geosparql/pom.xml index 98a482a35da..ee4e8c2e02e 100644 --- a/compliance/geosparql/pom.xml +++ b/compliance/geosparql/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-compliance - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-geosparql-compliance RDF4J: GeoSPARQL compliance tests diff --git a/compliance/lucene/pom.xml b/compliance/lucene/pom.xml index 68d0024e68a..2afc2a34c99 100644 --- a/compliance/lucene/pom.xml +++ b/compliance/lucene/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-compliance - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-lucene-compliance RDF4J: Lucene Sail Tests diff --git a/compliance/model/pom.xml b/compliance/model/pom.xml index 775a32482ab..43745d0d22a 100644 --- a/compliance/model/pom.xml +++ b/compliance/model/pom.xml @@ -3,7 +3,7 @@ rdf4j-compliance org.eclipse.rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT 4.0.0 rdf4j-model-compliance diff --git a/compliance/pom.xml b/compliance/pom.xml index 67fbedd4230..25bb1a984f3 100644 --- a/compliance/pom.xml +++ b/compliance/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-compliance pom diff --git a/compliance/repository/pom.xml b/compliance/repository/pom.xml index 2086d25b124..4d1642cc9e9 100644 --- a/compliance/repository/pom.xml +++ b/compliance/repository/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-compliance - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-repository-compliance war diff --git a/compliance/rio/pom.xml b/compliance/rio/pom.xml index a0decc202a2..b2d22802dc6 100644 --- a/compliance/rio/pom.xml +++ b/compliance/rio/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-compliance - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-rio-compliance RDF4J: Rio compliance tests diff --git a/compliance/solr/pom.xml b/compliance/solr/pom.xml index 2d8a77d73e2..2bb8b044e0a 100644 --- a/compliance/solr/pom.xml +++ b/compliance/solr/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-compliance - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-solr-compliance RDF4J: Solr Sail Tests diff --git a/compliance/sparql/pom.xml b/compliance/sparql/pom.xml index 42008ecfdf3..4f85a0c09e1 100644 --- a/compliance/sparql/pom.xml +++ b/compliance/sparql/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-compliance - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-sparql-compliance war diff --git a/core/client/pom.xml b/core/client/pom.xml index 83b3c43ec32..7cc1c61cf91 100644 --- a/core/client/pom.xml +++ b/core/client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-client RDF4J: Client Libraries diff --git a/core/collection-factory/api/pom.xml b/core/collection-factory/api/pom.xml index 6f810989f5c..be1452b7514 100644 --- a/core/collection-factory/api/pom.xml +++ b/core/collection-factory/api/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-collection-factory - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-collection-factory-api RDF4J: Collection Factory - API diff --git a/core/collection-factory/mapdb/pom.xml b/core/collection-factory/mapdb/pom.xml index 5553d014aef..837789ddc5f 100644 --- a/core/collection-factory/mapdb/pom.xml +++ b/core/collection-factory/mapdb/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-collection-factory - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-collection-factory-mapdb RDF4J: Collection Factory - Map DB backed diff --git a/core/collection-factory/mapdb3/pom.xml b/core/collection-factory/mapdb3/pom.xml index 0a463015a33..bbfc353aa78 100644 --- a/core/collection-factory/mapdb3/pom.xml +++ b/core/collection-factory/mapdb3/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-collection-factory - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-collection-factory-mapdb3 RDF4J: Collection Factory - Map DB v3 backed diff --git a/core/collection-factory/pom.xml b/core/collection-factory/pom.xml index 2a8a5e59a07..631395e0738 100644 --- a/core/collection-factory/pom.xml +++ b/core/collection-factory/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-collection-factory pom diff --git a/core/common/annotation/pom.xml b/core/common/annotation/pom.xml index 767c5eb176f..299ec3569a1 100644 --- a/core/common/annotation/pom.xml +++ b/core/common/annotation/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-common - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common-annotation RDF4J: common annotation diff --git a/core/common/exception/pom.xml b/core/common/exception/pom.xml index 65db79b1eae..787f801ecbc 100644 --- a/core/common/exception/pom.xml +++ b/core/common/exception/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-common - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common-exception RDF4J: common exception diff --git a/core/common/io/pom.xml b/core/common/io/pom.xml index 0e8be0a7d68..803ea846d0f 100644 --- a/core/common/io/pom.xml +++ b/core/common/io/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-common - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common-io RDF4J: common IO diff --git a/core/common/iterator/pom.xml b/core/common/iterator/pom.xml index 885a0e57294..5d3118ee786 100644 --- a/core/common/iterator/pom.xml +++ b/core/common/iterator/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-common - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common-iterator RDF4J: common iterators diff --git a/core/common/order/pom.xml b/core/common/order/pom.xml index fcb5c3c5b2a..1acbf8a8a81 100644 --- a/core/common/order/pom.xml +++ b/core/common/order/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-common - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common-order RDF4J: common order diff --git a/core/common/pom.xml b/core/common/pom.xml index 3e7f726d0c4..95b37fd0f42 100644 --- a/core/common/pom.xml +++ b/core/common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common pom diff --git a/core/common/text/pom.xml b/core/common/text/pom.xml index bb7ec77bd87..7f0232992b9 100644 --- a/core/common/text/pom.xml +++ b/core/common/text/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-common - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common-text RDF4J: common text diff --git a/core/common/transaction/pom.xml b/core/common/transaction/pom.xml index 9d3f9c3aadb..d4d272e46c0 100644 --- a/core/common/transaction/pom.xml +++ b/core/common/transaction/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-common - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common-transaction RDF4J: common transaction diff --git a/core/common/xml/pom.xml b/core/common/xml/pom.xml index 9deab59516e..ae86bb3bf9b 100644 --- a/core/common/xml/pom.xml +++ b/core/common/xml/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-common - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-common-xml RDF4J: common XML diff --git a/core/http/client/pom.xml b/core/http/client/pom.xml index 5823b5a2c25..fa30ef4d812 100644 --- a/core/http/client/pom.xml +++ b/core/http/client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-http - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-http-client RDF4J: HTTP client diff --git a/core/http/pom.xml b/core/http/pom.xml index 39ced0c2c00..fb8565845b1 100644 --- a/core/http/pom.xml +++ b/core/http/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-http pom diff --git a/core/http/protocol/pom.xml b/core/http/protocol/pom.xml index 56d2ef2d7df..74755a5a36e 100644 --- a/core/http/protocol/pom.xml +++ b/core/http/protocol/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-http - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-http-protocol RDF4J: HTTP protocol diff --git a/core/model-api/pom.xml b/core/model-api/pom.xml index 58aab5e4744..999e2bf07c6 100644 --- a/core/model-api/pom.xml +++ b/core/model-api/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-model-api RDF4J: Model API diff --git a/core/model-vocabulary/pom.xml b/core/model-vocabulary/pom.xml index 2d13366a736..830ed0d0c73 100644 --- a/core/model-vocabulary/pom.xml +++ b/core/model-vocabulary/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-model-vocabulary RDF4J: RDF Vocabularies diff --git a/core/model/pom.xml b/core/model/pom.xml index 005024521c6..dc9f7553e49 100644 --- a/core/model/pom.xml +++ b/core/model/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-model RDF4J: Model diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Configurations.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Configurations.java index 4bb8a37689f..b74e2f84ec4 100644 --- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Configurations.java +++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Configurations.java @@ -165,7 +165,13 @@ public static Set getPropertyValues(Model model, Resource subject, IRI pr var fallbackObjects = model.filter(subject, fallbackProperty, null).objects(); if (!fallbackObjects.isEmpty() && !preferredObjects.equals(fallbackObjects)) { - logger.warn("Discrepancy between use of the old and new config vocabulary."); + var msg = "Discrepancy between use of the old and new config vocabulary."; + // depending on whether preferred is set, we log on warn or debug + if (preferredObjects.isEmpty()) { + logger.debug(msg); + } else { + logger.warn(msg); + } if (preferredObjects.containsAll(fallbackObjects)) { return preferredObjects; @@ -235,7 +241,13 @@ public static Optional getSubjectByType(Model model, IRI type, IRI leg private static void logDiscrepancyWarning(Optional preferred, Optional fallback) { if (!fallback.isEmpty() && !preferred.equals(fallback)) { - logger.warn("Discrepancy between use of the old and new config vocabulary."); + var msg = "Discrepancy between use of the old and new config vocabulary."; + // depending on whether preferred is set, we log on warn or debug + if (preferred.isEmpty()) { + logger.debug(msg); + } else { + logger.warn(msg); + } } } } diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/util/ConfigurationsTest.java b/core/model/src/test/java/org/eclipse/rdf4j/model/util/ConfigurationsTest.java index 7a57ccb53e3..c0d9e026675 100644 --- a/core/model/src/test/java/org/eclipse/rdf4j/model/util/ConfigurationsTest.java +++ b/core/model/src/test/java/org/eclipse/rdf4j/model/util/ConfigurationsTest.java @@ -101,6 +101,7 @@ public void testGetLiteralValue_no_discrepancy() { var result = Configurations.getLiteralValue(m, subject, RDFS.LABEL, RDFS.COMMENT); assertThat(result).contains(literal("label")); assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.WARN); + assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.DEBUG); } @Test @@ -116,7 +117,21 @@ public void testGetLiteralValue_useLegacy_onlyNew() { System.setProperty("org.eclipse.rdf4j.model.vocabulary.useLegacyConfig", ""); assertThat(result).contains(literal("label")); - assertLogged("Discrepancy between use of the old and new config vocabulary.", Level.WARN); + assertLogged("Discrepancy between use of the old and new config vocabulary.", Level.DEBUG); + } + + @Test + public void testGetLiteralValue_onlyLegacy() { + + var subject = bnode(); + var m = new ModelBuilder().subject(subject) + .add(RDFS.COMMENT, "comment") + .build(); + + var result = Configurations.getLiteralValue(m, subject, RDFS.LABEL, RDFS.COMMENT); + + assertThat(result).contains(literal("comment")); + assertLogged("Discrepancy between use of the old and new config vocabulary.", Level.DEBUG); } @Test @@ -158,6 +173,7 @@ public void testGetResourceValue_no_discrepancy() { var result = Configurations.getResourceValue(m, subject, RDFS.LABEL, RDFS.COMMENT); assertThat(result).contains(iri("urn:label")); assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.WARN); + assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.DEBUG); } @Test @@ -183,6 +199,7 @@ public void testGetIRIValue_no_discrepancy() { var result = Configurations.getIRIValue(m, subject, RDFS.LABEL, RDFS.COMMENT); assertThat(result).contains(iri("urn:label")); assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.WARN); + assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.DEBUG); } @Test @@ -197,6 +214,7 @@ public void testGetPropertyValues_no_legacy() { var result = Configurations.getPropertyValues(m, subject, RDFS.LABEL, RDFS.COMMENT); assertThat(result).hasSize(2); assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.WARN); + assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.DEBUG); } @Test @@ -213,6 +231,7 @@ public void testGetPropertyValues_no_discrepancy() { var result = Configurations.getPropertyValues(m, subject, RDFS.LABEL, RDFS.COMMENT); assertThat(result).hasSize(2); assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.WARN); + assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.DEBUG); } @Test @@ -229,6 +248,7 @@ public void testGetPropertyValues_useLegacy_no_discrepancy() { var result = Configurations.getPropertyValues(m, subject, RDFS.LABEL, RDFS.COMMENT); assertThat(result).hasSize(2); assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.WARN); + assertNotLogged("Discrepancy between use of the old and new config vocabulary.", Level.DEBUG); } @Test diff --git a/core/pom.xml b/core/pom.xml index 6d214c405c3..c6cad1c1dbc 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-core pom diff --git a/core/query/pom.xml b/core/query/pom.xml index d8c876415f0..fd2e3aaf2b9 100644 --- a/core/query/pom.xml +++ b/core/query/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-query RDF4J: Query diff --git a/core/queryalgebra/evaluation/pom.xml b/core/queryalgebra/evaluation/pom.xml index 5b8f2d70f69..b82eaf35463 100644 --- a/core/queryalgebra/evaluation/pom.xml +++ b/core/queryalgebra/evaluation/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-queryalgebra - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-queryalgebra-evaluation RDF4J: Query algebra - evaluation diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/values/QueryValueEvaluationStepSupplier.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/values/QueryValueEvaluationStepSupplier.java index da0f8aeed6a..15ad8eb7d64 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/values/QueryValueEvaluationStepSupplier.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/values/QueryValueEvaluationStepSupplier.java @@ -50,7 +50,7 @@ private QueryValueEvaluationStepSupplier() { } public static QueryValueEvaluationStep prepareStr(QueryValueEvaluationStep arg, ValueFactory valueFactory) { - return make(arg, "Unkown constant argument for STR()", bs -> str(arg, valueFactory, bs)); + return make(arg, "Unknown constant argument for STR()", bs -> str(arg, valueFactory, bs)); } private static Value str(QueryValueEvaluationStep arg, ValueFactory valueFactory, BindingSet bindings) { @@ -67,7 +67,7 @@ private static Value str(QueryValueEvaluationStep arg, ValueFactory valueFactory return valueFactory.createLiteral(literal.getLabel()); } } else { - throw new ValueExprEvaluationException("Unkown constant argument for STR()"); + throw new ValueExprEvaluationException("Unknown constant argument for STR()"); } } diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIterator.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIterator.java index a860d9430f9..7f7b290771c 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIterator.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/GroupIterator.java @@ -30,6 +30,7 @@ import org.eclipse.rdf4j.collection.factory.api.CollectionFactory; import org.eclipse.rdf4j.collection.factory.impl.DefaultCollectionFactory; import org.eclipse.rdf4j.common.iteration.AbstractCloseableIteratorIteration; +import org.eclipse.rdf4j.common.iteration.CloseableIteration; import org.eclipse.rdf4j.common.transaction.QueryEvaluationMode; import org.eclipse.rdf4j.model.Literal; import org.eclipse.rdf4j.model.Value; @@ -89,6 +90,9 @@ public class GroupIterator extends AbstractCloseableIteratorIteration argumentsIter; + private final ValueFactory vf; private final CollectionFactory cf; @@ -129,7 +133,13 @@ public GroupIterator(EvaluationStrategy strategy, Group group, BindingSet parent @Override public void handleClose() throws QueryEvaluationException { - cf.close(); + try { + cf.close(); + } finally { + var iter = argumentsIter; + if (iter != null) + iter.close(); + } } @Override @@ -256,42 +266,46 @@ private BiConsumer makeBindSolution( private Collection buildEntries(List> aggregates) throws QueryEvaluationException { - try (var iter = arguments.evaluate(parentBindings)) { + // store the arguments' iterator so it can be closed while building entries + this.argumentsIter = arguments.evaluate(parentBindings); + try (var iter = argumentsIter) { + if (!iter.hasNext()) { + return emptySolutionSpecialCase(aggregates); + } + List> getValues = group.getGroupBindingNames() .stream() .map(n -> context.getValue(n)) .collect(Collectors.toList()); - if (!iter.hasNext()) { - return emptySolutionSpecialCase(aggregates); - } else { - // TODO: this is an in memory map with no backing into any disk form. - // Fixing this requires separating the computation of the aggregates and their - // distinct sets if needed from the intermediary values. - - Map entries = cf.createGroupByMap(); - // Make an optimized hash function valid during this query evaluation step. - ToIntFunction hashMaker = cf.hashOfBindingSetFuntion(getValues); - while (iter.hasNext()) { - BindingSet sol = iter.next(); - // The binding set key will be constant - BindingSetKey key = cf.createBindingSetKey(sol, getValues, hashMaker); - Entry entry = entries.get(key); - if (entry == null) { - List collectors = makeCollectors(aggregates); - List> predicates = new ArrayList<>(aggregates.size()); - for (AggregatePredicateCollectorSupplier a : aggregates) { - predicates.add(a.makePotentialDistinctTest.get()); - } - - entry = new Entry(sol, collectors, predicates); - entries.put(key, entry); + // TODO: this is an in memory map with no backing into any disk form. + // Fixing this requires separating the computation of the aggregates and their + // distinct sets if needed from the intermediary values. + + Map entries = cf.createGroupByMap(); + // Make an optimized hash function valid during this query evaluation step. + ToIntFunction hashMaker = cf.hashOfBindingSetFuntion(getValues); + while (!isClosed() && iter.hasNext()) { + BindingSet sol = iter.next(); + // The binding set key will be constant + BindingSetKey key = cf.createBindingSetKey(sol, getValues, hashMaker); + Entry entry = entries.get(key); + if (entry == null) { + List collectors = makeCollectors(aggregates); + List> predicates = new ArrayList<>(aggregates.size()); + for (AggregatePredicateCollectorSupplier a : aggregates) { + predicates.add(a.makePotentialDistinctTest.get()); } - entry.addSolution(sol, aggregates); + entry = new Entry(sol, collectors, predicates); + entries.put(key, entry); } - return entries.values(); + + entry.addSolution(sol, aggregates); } + return entries.values(); + } finally { + this.argumentsIter = null; } } diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/PeekMarkIterator.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/PeekMarkIterator.java index 55b412a2267..7849e60adbe 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/PeekMarkIterator.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/PeekMarkIterator.java @@ -39,7 +39,7 @@ public class PeekMarkIterator implements CloseableIteration { private boolean closed; - PeekMarkIterator(CloseableIteration iterator) { + public PeekMarkIterator(CloseableIteration 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 evaluate(TupleExpr tupleEx blockClose.increment(); try { + activeThread.setRelease(Thread.currentThread()); + verifyIsOpen(); CloseableIteration iteration = null; try { @@ -354,7 +342,11 @@ public final CloseableIteration evaluate(TupleExpr tupleEx throw t; } } finally { - unblockClose.increment(); + try { + activeThread.setRelease(null); + } finally { + unblockClose.increment(); + } } } @@ -364,10 +356,16 @@ public final CloseableIteration 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 getStatements(Resource subj blockClose.increment(); try { + activeThread.setRelease(Thread.currentThread()); verifyIsOpen(); CloseableIteration iteration = null; try { @@ -390,7 +389,11 @@ public final CloseableIteration 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 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 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 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 iterator() { return new LoggingCloseableIteration(this, validationExecutionLogger) { - ArrayDeque left; + LinkedHashMap left; ArrayDeque right; ArrayDeque joined; - private CloseableIteration leftNodeIterator; + private PeekMarkIterator 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 iterator() { ArrayDeque left; ArrayDeque right; - private CloseableIteration leftNodeIterator; + private PeekMarkIterator 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 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 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 tuples = new MockConsumePlanNode(innerJoin).asList(); @@ -90,7 +90,7 @@ public void testSimple4() { PlanNode left = new MockInputPlanNode(List.of("a1"), List.of("a2")); PlanNode right = new MockInputPlanNode(List.of()); - 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(); @@ -106,7 +106,7 @@ public void testSimple5() { PlanNode left = new MockInputPlanNode(); PlanNode right = new MockInputPlanNode(List.of("a1"), List.of("a2")); - 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(); @@ -124,7 +124,7 @@ public void testSimple6() { PlanNode right = new MockInputPlanNode(Arrays.asList("a1", "b1"), Arrays.asList("a2", "b2"), Arrays.asList("a3", "b3"), Arrays.asList("a4", "b4")); - 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(); @@ -141,7 +141,7 @@ public void testSimple7() { PlanNode left = new MockInputPlanNode(List.of("a1"), List.of("a2")); PlanNode right = new MockInputPlanNode(Arrays.asList("a1", "b1"), Arrays.asList("a2", "b2")); - 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(); @@ -158,7 +158,7 @@ public void testSimple8() { PlanNode right = new MockInputPlanNode(Arrays.asList("a1", "b1"), Arrays.asList("a2", "b2"), Arrays.asList("a3", "b3")); - 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(); @@ -176,7 +176,7 @@ public void testSimple9() { PlanNode right = new MockInputPlanNode(Arrays.asList("a1", "b1"), Arrays.asList("a2", "b2"), Arrays.asList("a2", "b22"), Arrays.asList("a3", "b3"), Arrays.asList("a4", "b4")); - 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(); @@ -195,7 +195,7 @@ public void testSimple10() { PlanNode right = new MockInputPlanNode(Arrays.asList("a1", "b1"), Arrays.asList("a2", "b2"), Arrays.asList("a2", "b22"), Arrays.asList("a4", "b4")); - 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(); @@ -214,7 +214,7 @@ public void testSimple11() { PlanNode right = new MockInputPlanNode(Arrays.asList("a2", "b2"), Arrays.asList("a2", "b22"), Arrays.asList("a4", "b4")); - 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(); @@ -231,7 +231,7 @@ public void testSimple12() { List.of("a4")); PlanNode right = new MockInputPlanNode(Arrays.asList("a2", "b2"), Arrays.asList("a2", "b22")); - 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(); @@ -249,7 +249,7 @@ public void testSimple13() { PlanNode right = new MockInputPlanNode(Arrays.asList("a1", "b1"), Arrays.asList("a1", "b11"), Arrays.asList("a2", "b2"), Arrays.asList("a2", "b22")); - 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(); diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedTest.java index 89aea92cac9..be87b248131 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedTest.java @@ -46,6 +46,7 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.parallel.Isolated; import org.slf4j.LoggerFactory; @@ -67,6 +68,7 @@ public static void afterAll() { } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testDataAndShapes() { System.out.println("testDataAndShapes"); @@ -339,6 +341,7 @@ private void remove(String turtle, IRI graph) { } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testLotsOfValidationFailuresSnapshot() throws IOException { System.out.println("testLotsOfValidationFailuresSnapshot"); ShaclSail sail = new ShaclSail(getBaseSail()); @@ -354,6 +357,7 @@ public void testLotsOfValidationFailuresSnapshot() throws IOException { } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testLotsOfValidationFailuresSerializableValidation() throws IOException { System.out.println("testLotsOfValidationFailuresSerializableValidation"); Logger root = (Logger) LoggerFactory.getLogger(ShaclSailBaseConfiguration.class.getName()); @@ -371,6 +375,7 @@ public void testLotsOfValidationFailuresSerializableValidation() throws IOExcept } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testLotsOfValidationFailuresSerializable() throws IOException { System.out.println("testLotsOfValidationFailuresSerializable"); @@ -389,6 +394,7 @@ public void testLotsOfValidationFailuresSerializable() throws IOException { } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testLotsOfValidationFailuresReadCommitted() throws IOException { System.out.println("testLotsOfValidationFailuresReadCommitted"); ShaclSail sail = new ShaclSail(getBaseSail()); @@ -403,6 +409,7 @@ public void testLotsOfValidationFailuresReadCommitted() throws IOException { } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testLotsOfValidationFailuresReadUncommitted() throws IOException { System.out.println("testLotsOfValidationFailuresReadUncommitted"); ShaclSail sail = new ShaclSail(getBaseSail()); diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclTestWithoutSparqlValidationTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclTestWithoutSparqlValidationTest.java new file mode 100644 index 00000000000..a3b4c123299 --- /dev/null +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclTestWithoutSparqlValidationTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * 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.shacl; + +import org.eclipse.rdf4j.common.transaction.IsolationLevel; +import org.eclipse.rdf4j.repository.sail.SailRepository; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * @author Håvard Ottestad + */ +public class ShaclTestWithoutSparqlValidationTest extends AbstractShaclTest { + + @Override + SailRepository getShaclSail(TestCase testCase) { + SailRepository sail = super.getShaclSail(testCase); + ShaclSail shaclSail = (ShaclSail) sail.getSail(); + shaclSail.sparqlValidation = false; + return sail; + } + + @ParameterizedTest + @MethodSource("testsToRunWithIsolationLevel") + public void test(TestCase testCase, IsolationLevel isolationLevel) { + runWithAutomaticLogging(() -> runTestCase(testCase, isolationLevel, false)); + } + + @ParameterizedTest + @MethodSource("testCases") + public void testSingleTransaction(TestCase testCase) { + runWithAutomaticLogging(() -> runTestCaseSingleTransaction(testCase)); + } + + @ParameterizedTest + @MethodSource("testsToRunWithIsolationLevel") + public void testRevalidation(TestCase testCase, IsolationLevel isolationLevel) { + runWithAutomaticLogging(() -> runTestCaseRevalidate(testCase, isolationLevel)); + } + + @ParameterizedTest + @MethodSource("testsToRunWithIsolationLevel") + public void testNonEmpty(TestCase testCase, IsolationLevel isolationLevel) { + runWithAutomaticLogging(() -> runTestCase(testCase, isolationLevel, true)); + } + + @ParameterizedTest + @MethodSource("testCases") + public void testParsing(TestCase testCase) { + runWithAutomaticLogging(() -> runParsingTest(testCase)); + } + + @ParameterizedTest + @MethodSource("testCases") + public void testReferenceImplementation(TestCase testCase) { + runWithAutomaticLogging(() -> referenceImplementationTestCaseValidation(testCase)); + } + + @ParameterizedTest + @MethodSource("testCases") + public void testShaclValidator(TestCase testCase) { + runWithAutomaticLogging(() -> runWithShaclValidator(testCase)); + } + +} diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/UniqueTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/UniqueTest.java index 11d1347349e..16e04b43cc3 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/UniqueTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/UniqueTest.java @@ -82,7 +82,7 @@ public void compressPropertyShape2() { Arrays.asList("a", "a", "2") ); - PlanNode unique = Unique.getInstance(input, true); + PlanNode unique = Unique.getInstance(input, true, null); List tuples = new MockConsumePlanNode(unique).asList(); @@ -91,7 +91,7 @@ public void compressPropertyShape2() { } private void runTest(MockInputPlanNode input, boolean compress) { - PlanNode unique = Unique.getInstance(input, compress); + PlanNode unique = Unique.getInstance(input, compress, null); List tuples = new MockConsumePlanNode(unique).asList(); diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java index a64f42077f3..a72a41c0196 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java @@ -12,6 +12,7 @@ package org.eclipse.rdf4j.sail.shacl; import java.io.BufferedInputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -137,7 +138,7 @@ public static void loadInitialData(SailRepository repo, String resourceName) thr try (RepositoryConnection conn = repo.getConnection()) { conn.begin(IsolationLevels.NONE, ShaclSail.TransactionSettings.ValidationApproach.Disabled); - conn.add(initialData, "", RDFFormat.TURTLE); + conn.add(initialData, "", RDFFormat.TRIG); conn.commit(); } } diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ast/targets/StableQueryGenerationTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ast/targets/StableQueryGenerationTest.java index e4f68e5b36c..04f7ab0033a 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ast/targets/StableQueryGenerationTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ast/targets/StableQueryGenerationTest.java @@ -71,22 +71,28 @@ public void testNormalizationOfQuery() { }; String test1 = names[4] + names[4] + names[9]; - assertEquals(names[0] + names[0] + names[1], StatementMatcher.StableRandomVariableProvider.normalize(test1)); + assertEquals(names[0] + names[0] + names[1], + StatementMatcher.StableRandomVariableProvider.normalize(test1, List.of(), List.of())); String test2 = names[9] + names[4] + names[9]; - assertEquals(names[1] + names[0] + names[1], StatementMatcher.StableRandomVariableProvider.normalize(test2)); + assertEquals(names[1] + names[0] + names[1], + StatementMatcher.StableRandomVariableProvider.normalize(test2, List.of(), List.of())); String test3 = names[0] + names[1] + names[2]; - assertEquals(names[0] + names[1] + names[2], StatementMatcher.StableRandomVariableProvider.normalize(test3)); + assertEquals(names[0] + names[1] + names[2], + StatementMatcher.StableRandomVariableProvider.normalize(test3, List.of(), List.of())); String test4 = names[1] + names[2] + names[3]; - assertEquals(names[0] + names[1] + names[2], StatementMatcher.StableRandomVariableProvider.normalize(test4)); + assertEquals(names[0] + names[1] + names[2], + StatementMatcher.StableRandomVariableProvider.normalize(test4, List.of(), List.of())); String test5 = names[2] + names[4] + names[8]; - assertEquals(names[0] + names[1] + names[2], StatementMatcher.StableRandomVariableProvider.normalize(test5)); + assertEquals(names[0] + names[1] + names[2], + StatementMatcher.StableRandomVariableProvider.normalize(test5, List.of(), List.of())); String test6 = names[8] + names[4] + names[2]; - assertEquals(names[2] + names[1] + names[0], StatementMatcher.StableRandomVariableProvider.normalize(test6)); + assertEquals(names[2] + names[1] + names[0], + StatementMatcher.StableRandomVariableProvider.normalize(test6, List.of(), List.of())); } diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/BenchmarkConfigs.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/BenchmarkConfigs.java index 4e43cbb8391..fd6b8807982 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/BenchmarkConfigs.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/BenchmarkConfigs.java @@ -24,18 +24,25 @@ public class BenchmarkConfigs { public static List> generateStatements(StatementCreator statementCreator) { + return generateStatements(NUMBER_OF_TRANSACTIONS, STATEMENTS_PER_TRANSACTION, NUMBER_OF_EMPTY_TRANSACTIONS, + statementCreator); + } + + public static List> generateStatements(int numberOfTransactions, int statementsPerTransaction, + int numberOfEmptyTransactions, StatementCreator statementCreator) { + List> allStatements = new ArrayList<>(); - for (int j = 0; j < BenchmarkConfigs.NUMBER_OF_TRANSACTIONS; j++) { + for (int j = 0; j < numberOfTransactions; j++) { List statements = new ArrayList<>(); allStatements.add(statements); - for (int i = 0; i < BenchmarkConfigs.STATEMENTS_PER_TRANSACTION; i++) { + for (int i = 0; i < statementsPerTransaction; i++) { statementCreator.createStatement(statements, i, j); } } - for (int j = 0; j < BenchmarkConfigs.NUMBER_OF_EMPTY_TRANSACTIONS; j++) { + for (int j = 0; j < numberOfEmptyTransactions; j++) { List statements = new ArrayList<>(); allStatements.add(statements); } diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ClassBenchmarkEmpty.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ClassBenchmarkEmpty.java index 5271639b657..e02b47859ce 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ClassBenchmarkEmpty.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ClassBenchmarkEmpty.java @@ -72,13 +72,23 @@ public void setUp() throws InterruptedException { Thread.sleep(100); } + public static void main(String[] args) throws Exception { + ClassBenchmarkEmpty classBenchmarkEmpty = new ClassBenchmarkEmpty(); + classBenchmarkEmpty.setUp(); + classBenchmarkEmpty.shacl(); + + } + @Benchmark public void shacl() throws Exception { SailRepository repository = new SailRepository(Utils.getInitializedShaclSail("shaclClassBenchmark.trig")); +// ((ShaclSail) repository.getSail()).setLogValidationPlans(true); + try (SailRepositoryConnection connection = repository.getConnection()) { for (List statements : allStatements) { +// System.out.println("."); connection.begin(); connection.add(statements); connection.commit(); diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ComplexLargeBenchmark.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ComplexLargeBenchmark.java index 5568410f292..a40d5bc191b 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ComplexLargeBenchmark.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ComplexLargeBenchmark.java @@ -117,9 +117,9 @@ public void teardown() { public static void main(String[] args) throws InterruptedException { ComplexLargeBenchmark complexLargeBenchmark = new ComplexLargeBenchmark(); complexLargeBenchmark.setUp(); - for (int i = 0; i < 20; i++) { + for (int i = 0; i < 100; i++) { System.out.println(i); - complexLargeBenchmark.noPreloadingNonEmptyParallel(); + complexLargeBenchmark.noPreloadingNonEmptyParallelRemoved(); } complexLargeBenchmark.teardown(); } @@ -416,7 +416,7 @@ public void noPreloadingNonEmptyParallelRemoved() { ((ShaclSail) repository.getSail()).setParallelValidation(true); ((ShaclSail) repository.getSail()).setCacheSelectNodes(true); - ((ShaclSail) repository.getSail()).setPerformanceLogging(false); +// ((ShaclSail) repository.getSail()).setPerformanceLogging(true); try (SailRepositoryConnection connection = repository.getConnection()) { connection.begin(IsolationLevels.NONE); diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/MaxCountSparqlBenchmarkEmpty.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/MaxCountSparqlBenchmarkEmpty.java new file mode 100644 index 00000000000..9009fa2cd53 --- /dev/null +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/MaxCountSparqlBenchmarkEmpty.java @@ -0,0 +1,300 @@ +/******************************************************************************* + * 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.shacl.benchmark; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Statement; +import org.eclipse.rdf4j.model.impl.SimpleValueFactory; +import org.eclipse.rdf4j.model.vocabulary.RDF; +import org.eclipse.rdf4j.model.vocabulary.RDFS; +import org.eclipse.rdf4j.repository.RepositoryException; +import org.eclipse.rdf4j.repository.sail.SailRepository; +import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; +import org.eclipse.rdf4j.sail.shacl.ShaclSail; +import org.eclipse.rdf4j.sail.shacl.ShaclSailConnection; +import org.eclipse.rdf4j.sail.shacl.ShaclSailValidationException; +import org.eclipse.rdf4j.sail.shacl.Utils; +import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.MaxCountConstraintComponent; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Logger; + +/** + * @author Håvard Ottestad + */ +@State(Scope.Benchmark) +@Warmup(iterations = 5) +@BenchmarkMode({ Mode.AverageTime }) +@Fork(value = 1, jvmArgs = { "-Xmx2G", "-Xms2G" }) +@Measurement(iterations = 5) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +public class MaxCountSparqlBenchmarkEmpty { + + @Param({ "1", "2", "3", "4" }) + public int MAX_COUNT = 1; + + @Param({ "manyInvalidStatements", "mostlyValidStatements" }) + public String statementList; + + private static List> manyInvalidStatements; + private static List> mostlyValidStatements1; + private static List> mostlyValidStatements2; + private static List> mostlyValidStatements3; + private static List> mostlyValidStatements4; + + static { + fillData(); + } + + @Setup(Level.Trial) + public void setUp() throws InterruptedException { + + Logger root = (Logger) LoggerFactory.getLogger(ShaclSailConnection.class.getName()); + root.setLevel(ch.qos.logback.classic.Level.INFO); + + System.gc(); + Thread.sleep(100); + } + + private static void fillData() { + SimpleValueFactory vf = SimpleValueFactory.getInstance(); + + manyInvalidStatements = BenchmarkConfigs.generateStatements(1, 10, 0, ((statements, i, j) -> { + IRI iri = vf.createIRI("http://example.com/invalid_" + i + "_" + j); + + statements.add(vf.createStatement(iri, RDF.TYPE, RDFS.RESOURCE)); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label1" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label2" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label3" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label4" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label5" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label6" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label7" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label8" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label9" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label10" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label11" + "_" + i + "_" + j))); + + for (int i2 = 0; i2 < 1000; i2++) { + IRI validIri = vf.createIRI("http://example.com/valid" + i2 + "_" + i + "_" + j); + statements.add(vf.createStatement(validIri, RDF.TYPE, RDFS.RESOURCE)); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label1" + i2 + "_" + i + "_" + j))); + } + + })); + + mostlyValidStatements1 = BenchmarkConfigs.generateStatements(1, 1, 0, ((statements, i, j) -> { + IRI iri = vf.createIRI("http://example.com/invalid_" + i + "_" + j); + + statements.add(vf.createStatement(iri, RDF.TYPE, RDFS.RESOURCE)); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label1" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label2" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label3" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label4" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label5" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label6" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label7" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label8" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label9" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label10" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label11" + "_" + i + "_" + j))); + + for (int i2 = 0; i2 < 10000; i2++) { + IRI validIri = vf.createIRI("http://example.com/valid" + i2 + "_" + i + "_" + j); + statements.add(vf.createStatement(validIri, RDF.TYPE, RDFS.RESOURCE)); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label1" + i2 + "_" + i + "_" + j))); + } + + })); + + mostlyValidStatements2 = BenchmarkConfigs.generateStatements(1, 1, 0, ((statements, i, j) -> { + IRI iri = vf.createIRI("http://example.com/invalid_" + i + "_" + j); + + statements.add(vf.createStatement(iri, RDF.TYPE, RDFS.RESOURCE)); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label1" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label2" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label3" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label4" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label5" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label6" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label7" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label8" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label9" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label10" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label11" + "_" + i + "_" + j))); + + for (int i2 = 0; i2 < 10000; i2++) { + IRI validIri = vf.createIRI("http://example.com/valid" + i2 + "_" + i + "_" + j); + statements.add(vf.createStatement(validIri, RDF.TYPE, RDFS.RESOURCE)); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label1" + i2 + "_" + i + "_" + j))); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label2" + i2 + "_" + i + "_" + j))); + } + + })); + + mostlyValidStatements3 = BenchmarkConfigs.generateStatements(1, 1, 0, ((statements, i, j) -> { + IRI iri = vf.createIRI("http://example.com/invalid_" + i + "_" + j); + + statements.add(vf.createStatement(iri, RDF.TYPE, RDFS.RESOURCE)); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label1" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label2" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label3" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label4" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label5" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label6" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label7" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label8" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label9" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label10" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label11" + "_" + i + "_" + j))); + + for (int i2 = 0; i2 < 10000; i2++) { + IRI validIri = vf.createIRI("http://example.com/valid" + i2 + "_" + i + "_" + j); + statements.add(vf.createStatement(validIri, RDF.TYPE, RDFS.RESOURCE)); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label1" + i2 + "_" + i + "_" + j))); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label2" + i2 + "_" + i + "_" + j))); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label3" + i2 + "_" + i + "_" + j))); + } + + })); + + mostlyValidStatements4 = BenchmarkConfigs.generateStatements(1, 1, 0, ((statements, i, j) -> { + IRI iri = vf.createIRI("http://example.com/invalid_" + i + "_" + j); + + statements.add(vf.createStatement(iri, RDF.TYPE, RDFS.RESOURCE)); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label1" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label2" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label3" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label4" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label5" + i))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label6" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label7" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label8" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label9" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label10" + "_" + i + "_" + j))); + statements.add(vf.createStatement(iri, RDFS.LABEL, vf.createLiteral("label11" + "_" + i + "_" + j))); + + for (int i2 = 0; i2 < 10000; i2++) { + IRI validIri = vf.createIRI("http://example.com/valid" + i2 + "_" + i + "_" + j); + statements.add(vf.createStatement(validIri, RDF.TYPE, RDFS.RESOURCE)); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label1" + i2 + "_" + i + "_" + j))); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label2" + i2 + "_" + i + "_" + j))); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label3" + i2 + "_" + i + "_" + j))); + statements.add( + vf.createStatement(validIri, RDFS.LABEL, vf.createLiteral("label4" + i2 + "_" + i + "_" + j))); + } + + })); + } + + @TearDown(Level.Trial) + public void tearDown() { + MaxCountConstraintComponent.SPARQL_VALIDATION_APPROACH_LIMIT = 5; + } + + @Benchmark + public void shaclBulkSparql() throws Exception { + + MaxCountConstraintComponent.SPARQL_VALIDATION_APPROACH_LIMIT = 10; + + SailRepository repository = new SailRepository( + Utils.getInitializedShaclSail("shaclMaxCountBenchmark" + MAX_COUNT + ".trig")); + + try (SailRepositoryConnection connection = repository.getConnection()) { + connection.begin(ShaclSail.TransactionSettings.ValidationApproach.Bulk); + for (List statements : getStatements()) { + connection.add(statements); + } + try { + connection.commit(); + } catch (RepositoryException e) { + if (!(e.getCause() instanceof ShaclSailValidationException)) { + throw e; + } + } + } + repository.shutDown(); + + } + + private List> getStatements() { + if (statementList.equals("mostlyValidStatements")) { + statementList = "mostlyValidStatements" + MAX_COUNT; + } + + switch (statementList) { + case "manyInvalidStatements": + return manyInvalidStatements; + case "mostlyValidStatements1": + return mostlyValidStatements1; + case "mostlyValidStatements2": + return mostlyValidStatements2; + case "mostlyValidStatements3": + return mostlyValidStatements3; + case "mostlyValidStatements4": + return mostlyValidStatements4; + } + throw new IllegalStateException(); + } + + @Benchmark + public void shaclBulkNonSparql() throws Exception { + + MaxCountConstraintComponent.SPARQL_VALIDATION_APPROACH_LIMIT = 0; + + SailRepository repository = new SailRepository( + Utils.getInitializedShaclSail("shaclMaxCountBenchmark" + MAX_COUNT + ".trig")); + + try (SailRepositoryConnection connection = repository.getConnection()) { + connection.begin(ShaclSail.TransactionSettings.ValidationApproach.Bulk); + for (List statements : getStatements()) { + connection.add(statements); + } + try { + connection.commit(); + } catch (RepositoryException e) { + if (!(e.getCause() instanceof ShaclSailValidationException)) { + throw e; + } + } + } + repository.shutDown(); + + } + +} diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/SparqlConstraintsBenchmarkEmpty.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/SparqlConstraintsBenchmarkEmpty.java new file mode 100644 index 00000000000..8464583871b --- /dev/null +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/SparqlConstraintsBenchmarkEmpty.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * 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.shacl.benchmark; + +import java.net.URL; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.Statement; +import org.eclipse.rdf4j.model.impl.SimpleValueFactory; +import org.eclipse.rdf4j.model.vocabulary.RDF; +import org.eclipse.rdf4j.model.vocabulary.RDFS; +import org.eclipse.rdf4j.repository.sail.SailRepository; +import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; +import org.eclipse.rdf4j.rio.RDFFormat; +import org.eclipse.rdf4j.sail.shacl.ShaclSail; +import org.eclipse.rdf4j.sail.shacl.ShaclSailConnection; +import org.eclipse.rdf4j.sail.shacl.ShaclSailValidationException; +import org.eclipse.rdf4j.sail.shacl.Utils; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Logger; + +/** + * @author Håvard Ottestad + */ +@State(Scope.Benchmark) +@Warmup(iterations = 5) +@BenchmarkMode({ Mode.AverageTime }) +@Fork(value = 1, jvmArgs = { "-Xmx64M" }) +//@Fork(value = 1, jvmArgs = { "-Xms8G", "-Xmx8G", "-XX:StartFlightRecording=delay=15s,duration=120s,filename=recording.jfr,settings=profile", "-XX:FlightRecorderOptions=samplethreads=true,stackdepth=1024", "-XX:+UnlockDiagnosticVMOptions", "-XX:+DebugNonSafepoints" }) +@Measurement(iterations = 5) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +public class SparqlConstraintsBenchmarkEmpty { + + private List> allStatements; + + @Setup(Level.Trial) + public void setUp() throws InterruptedException { + Logger root = (Logger) LoggerFactory.getLogger(ShaclSailConnection.class.getName()); + root.setLevel(ch.qos.logback.classic.Level.INFO); + + System.gc(); + Thread.sleep(100); + } + + @Benchmark + public void shacl() throws Exception { + + SailRepository repository = new SailRepository(Utils.getInitializedShaclSail("benchmark/sparql/shacl.trig")); + + try (SailRepositoryConnection connection = repository.getConnection()) { + for (int i = 0; i < 10; i++) { + connection.begin(); + URL data = SparqlConstraintsBenchmarkEmpty.class.getClassLoader() + .getResource("benchmark/sparql/data.ttl"); + connection.add(data, RDFFormat.TURTLE); + try { + connection.commit(); + } catch (Exception e) { + + Model statements = ((ShaclSailValidationException) e.getCause()).validationReportAsModel(); + for (Statement statement : statements) { + System.out.println(statement); + } + System.exit(0); + connection.rollback(); + } + } + } + repository.shutDown(); + + } + + @Benchmark + public void shaclBulk() throws Exception { + + SailRepository repository = new SailRepository(Utils.getInitializedShaclSail("benchmark/sparql/shacl.trig")); + + try (SailRepositoryConnection connection = repository.getConnection()) { + connection.begin(ShaclSail.TransactionSettings.ValidationApproach.Bulk); + for (int i = 0; i < 10; i++) { + URL data = SparqlConstraintsBenchmarkEmpty.class.getClassLoader() + .getResource("benchmark/sparql/data.ttl"); + connection.add(data, RDFFormat.TURTLE); + } + connection.commit(); + } + repository.shutDown(); + + } + +} diff --git a/core/sail/shacl/src/test/resources/benchmark/sparql/data.ttl b/core/sail/shacl/src/test/resources/benchmark/sparql/data.ttl new file mode 100644 index 00000000000..cc2cc40587c --- /dev/null +++ b/core/sail/shacl/src/test/resources/benchmark/sparql/data.ttl @@ -0,0 +1,1114 @@ +@prefix : . +@prefix ont: . +@prefix vocsh: . +@prefix so: . +@prefix affected: . +@prefix res: . +@prefix dct: . +@prefix gn: . +@prefix owl: . +@prefix puml: . +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . +@prefix void: . +@prefix wgs84: . +@prefix xsd: . +@prefix sh: . +@prefix dash: . +@prefix rsx: . +@prefix ec: . +@prefix ecinst: . +@prefix rdf4j: . +@prefix ex: . + + + +[] a ex:Country ; + ex:knows [] . + + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + + + + +[] a ex:Country ; + ex:knows [] . + + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + + + + +[] a ex:Country ; + ex:knows [] . + + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + + + + +[] a ex:Country ; + ex:knows [] . + + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + + + + +[] a ex:Country ; + ex:knows [] . + + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + + + + +[] a ex:Country ; + ex:knows [] . + + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + + + + +[] a ex:Country ; + ex:knows [] . + + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + + +[] a ex:Country ; + ex:knows [] . + diff --git a/core/sail/shacl/src/test/resources/benchmark/sparql/shacl.trig b/core/sail/shacl/src/test/resources/benchmark/sparql/shacl.trig new file mode 100644 index 00000000000..da7ca2c5dec --- /dev/null +++ b/core/sail/shacl/src/test/resources/benchmark/sparql/shacl.trig @@ -0,0 +1,53 @@ +@prefix : . +@prefix ont: . +@prefix vocsh: . +@prefix so: . +@prefix affected: . +@prefix res: . +@prefix dct: . +@prefix gn: . +@prefix owl: . +@prefix puml: . +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . +@prefix void: . +@prefix wgs84: . +@prefix xsd: . +@prefix sh: . +@prefix dash: . +@prefix rsx: . +@prefix ec: . +@prefix ecinst: . +@prefix rdf4j: . +@prefix ex: . + +rdf4j:SHACLShapeGraph { + +ex: + sh:declare [ + sh:prefix "ex" ; + sh:namespace "http://example.com/ns#"^^xsd:anyURI ; + ] ; + sh:declare [ + sh:prefix "schema" ; + sh:namespace "http://schema.org/"^^xsd:anyURI ; + ] . + + ex:LanguageExamplePropertyShape + a sh:PropertyShape ; + sh:targetClass ex:Country ; + sh:path ex:knows ; + sh:sparql [ + a sh:SPARQLConstraint ; + sh:message "Values are blank nodes." ; + sh:prefixes ex: ; + sh:select """ + SELECT $this ?value + WHERE { + $this $PATH ?value . + FILTER (!isBlank(?value)) + } + """ ; + ] . +} diff --git a/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark1.trig b/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark1.trig new file mode 100644 index 00000000000..69fdb49d6f9 --- /dev/null +++ b/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark1.trig @@ -0,0 +1,20 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rdf4j: . + +rdf4j:SHACLShapeGraph { +ex:PersonShape + a sh:NodeShape ; + sh:targetClass rdfs:Resource ; + sh:property ex:PersonShapeProperty . + + +ex:PersonShapeProperty + sh:path rdfs:label ; + sh:maxCount 1 . + } diff --git a/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark2.trig b/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark2.trig new file mode 100644 index 00000000000..bfa21ded63a --- /dev/null +++ b/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark2.trig @@ -0,0 +1,20 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rdf4j: . + +rdf4j:SHACLShapeGraph { +ex:PersonShape + a sh:NodeShape ; + sh:targetClass rdfs:Resource ; + sh:property ex:PersonShapeProperty . + + +ex:PersonShapeProperty + sh:path rdfs:label ; + sh:maxCount 2 . + } diff --git a/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark3.trig b/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark3.trig new file mode 100644 index 00000000000..54d31d1e8e9 --- /dev/null +++ b/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark3.trig @@ -0,0 +1,20 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rdf4j: . + +rdf4j:SHACLShapeGraph { +ex:PersonShape + a sh:NodeShape ; + sh:targetClass rdfs:Resource ; + sh:property ex:PersonShapeProperty . + + +ex:PersonShapeProperty + sh:path rdfs:label ; + sh:maxCount 3 . + } diff --git a/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark4.trig b/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark4.trig new file mode 100644 index 00000000000..89a99484615 --- /dev/null +++ b/core/sail/shacl/src/test/resources/shaclMaxCountBenchmark4.trig @@ -0,0 +1,20 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rdf4j: . + +rdf4j:SHACLShapeGraph { +ex:PersonShape + a sh:NodeShape ; + sh:targetClass rdfs:Resource ; + sh:property ex:PersonShapeProperty . + + +ex:PersonShapeProperty + sh:path rdfs:label ; + sh:maxCount 4 . + } diff --git a/core/sail/shacl/src/test/resources/test-cases/class/complexPath/invalid/case7/query1.rq b/core/sail/shacl/src/test/resources/test-cases/class/complexPath/invalid/case7/query1.rq new file mode 100644 index 00000000000..847fa1bfb04 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/class/complexPath/invalid/case7/query1.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:AnyTarget, ex:Person, ex:SecondTarget ; + ex:knows1 [ ex:knows2 [ ex:knows3 [ ex:knows4 ex:peter ]]]. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/class/complexPath/invalid/case7/report.ttl b/core/sail/shacl/src/test/resources/test-cases/class/complexPath/invalid/case7/report.ttl new file mode 100644 index 00000000000..63394b1bf68 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/class/complexPath/invalid/case7/report.ttl @@ -0,0 +1,27 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:validPerson1; + sh:resultPath _:867c9670a0c541e184b71a3107a202a6598; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:ClassConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:class ex:Person; + sh:path _:867c9670a0c541e184b71a3107a202a6598 + ]; + sh:value ex:peter + ] . + +_:867c9670a0c541e184b71a3107a202a6598 rdf:first ex:knows1; + rdf:rest (ex:knows2 ex:knows3 ex:knows4) . diff --git a/core/sail/shacl/src/test/resources/test-cases/class/complexPath/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/class/complexPath/shacl.trig index 7a39648bd06..251283430ce 100644 --- a/core/sail/shacl/src/test/resources/test-cases/class/complexPath/shacl.trig +++ b/core/sail/shacl/src/test/resources/test-cases/class/complexPath/shacl.trig @@ -8,7 +8,7 @@ rdf4j:SHACLShapeGraph { ex:PersonShape a sh:NodeShape; - sh:targetClass ex:Person, ex:SecondTarget; + sh:targetClass ex:Person, ex:SecondTarget, ex:AnyTarget; sh:property [ sh:path (ex:knows1 ex:knows2 ex:knows3 ex:knows4); sh:class ex:Person diff --git a/core/sail/shacl/src/test/resources/test-cases/class/simple/invalid/case10/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/class/simple/invalid/case10/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/class/simple/invalid/case10/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/class/simple/invalid/case10/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case10/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case10/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case10/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case10/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case11/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case11/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case11/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case11/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case12/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case12/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case12/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/class/simpleNested/invalid/case12/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/class/subclass/invalid/case7/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/class/subclass/invalid/case7/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/class/subclass/invalid/case7/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/class/subclass/invalid/case7/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case1/query1.rq new file mode 100644 index 00000000000..69fc48d49a7 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case1/query1.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:Person ; + ex:knows1 [ex:knows2 [ex:knows3 [ex:knows4 ex:p1]]]. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case1/report.ttl new file mode 100644 index 00000000000..a41adf9d5ce --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case1/report.ttl @@ -0,0 +1,33 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode []; + sh:resultPath ex:knows2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:node [ a sh:NodeShape; + sh:property [ a sh:PropertyShape; + sh:path ex:knows3; + sh:property [ a sh:PropertyShape; + sh:datatype xsd:float; + sh:path ex:knows4 + ] + ] + ]; + sh:path ex:knows2 + ]; + sh:value [] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case2/query1.rq new file mode 100644 index 00000000000..7fd4a7dbe60 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case2/query1.rq @@ -0,0 +1,17 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:Person ; + ex:knows1 ex:p1. + +ex:p1 ex:knows2 ex:p2. +ex:p2 ex:knows3 ex:p3. +ex:p3 ex:knows4 ex:p4. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case2/report.ttl new file mode 100644 index 00000000000..49185f9ced7 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case2/report.ttl @@ -0,0 +1,33 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p1; + sh:resultPath ex:knows2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:node [ a sh:NodeShape; + sh:property [ a sh:PropertyShape; + sh:path ex:knows3; + sh:property [ a sh:PropertyShape; + sh:datatype xsd:float; + sh:path ex:knows4 + ] + ] + ]; + sh:path ex:knows2 + ]; + sh:value ex:p2 + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case3/query1.rq new file mode 100644 index 00000000000..daef27ca19f --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case3/query1.rq @@ -0,0 +1,18 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:Person ; + ex:knows1 ex:p1, ex:p1_1. + +ex:p1 ex:knows2 ex:p2. +ex:p1_1 ex:knows2 ex:p2. + +ex:p2 ex:knows3 ex:p3. +ex:p3 ex:knows4 ex:p4. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case3/report.ttl new file mode 100644 index 00000000000..b785f8d0007 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case3/report.ttl @@ -0,0 +1,43 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p1; + sh:resultPath ex:knows2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeConstraintComponent; + sh:sourceShape _:5089a376325a403b926b5c31d5e95e721475; + sh:value ex:p2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p1_1; + sh:resultPath ex:knows2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeConstraintComponent; + sh:sourceShape _:5089a376325a403b926b5c31d5e95e721475; + sh:value ex:p2 + ] . + +_:5089a376325a403b926b5c31d5e95e721475 a sh:PropertyShape; + sh:node [ a sh:NodeShape; + sh:property [ a sh:PropertyShape; + sh:path ex:knows3; + sh:property [ a sh:PropertyShape; + sh:datatype xsd:float; + sh:path ex:knows4 + ] + ] + ]; + sh:path ex:knows2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case4/query1.rq new file mode 100644 index 00000000000..a870343cf8f --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case4/query1.rq @@ -0,0 +1,21 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:Person ; + ex:knows1 ex:p1. + +ex:p1 ex:knows2 ex:p2. +ex:p1 ex:knows2 ex:p2_1. + +ex:p2_1 ex:knows3 ex:p3. +ex:p2 ex:knows3 ex:p3. + +ex:p3 ex:knows4 ex:p4. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case4/report.ttl new file mode 100644 index 00000000000..08bb47f7b81 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case4/report.ttl @@ -0,0 +1,43 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p1; + sh:resultPath ex:knows2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeConstraintComponent; + sh:sourceShape _:5089a376325a403b926b5c31d5e95e721758; + sh:value ex:p2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p1; + sh:resultPath ex:knows2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeConstraintComponent; + sh:sourceShape _:5089a376325a403b926b5c31d5e95e721758; + sh:value ex:p2_1 + ] . + +_:5089a376325a403b926b5c31d5e95e721758 a sh:PropertyShape; + sh:node [ a sh:NodeShape; + sh:property [ a sh:PropertyShape; + sh:path ex:knows3; + sh:property [ a sh:PropertyShape; + sh:datatype xsd:float; + sh:path ex:knows4 + ] + ] + ]; + sh:path ex:knows2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/query1.rq new file mode 100644 index 00000000000..604808ad27e --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/query1.rq @@ -0,0 +1,16 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:Person ; + ex:knows1 ex:p1. + +ex:p1 ex:knows2 ex:p2. +ex:p3 ex:knows4 ex:p4. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/query2.rq new file mode 100644 index 00000000000..76f7bb7430b --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/query2.rq @@ -0,0 +1,11 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:p2 ex:knows3 ex:p3. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/report.ttl b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/report.ttl new file mode 100644 index 00000000000..49185f9ced7 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case5/report.ttl @@ -0,0 +1,33 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p1; + sh:resultPath ex:knows2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:node [ a sh:NodeShape; + sh:property [ a sh:PropertyShape; + sh:path ex:knows3; + sh:property [ a sh:PropertyShape; + sh:datatype xsd:float; + sh:path ex:knows4 + ] + ] + ]; + sh:path ex:knows2 + ]; + sh:value ex:p2 + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/query1.rq new file mode 100644 index 00000000000..e26a99534fa --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/query1.rq @@ -0,0 +1,16 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:Person ; + ex:knows1 ex:p1. + +ex:p2 ex:knows3 ex:p3. +ex:p3 ex:knows4 ex:p4. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/query2.rq new file mode 100644 index 00000000000..712a06afa9c --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/query2.rq @@ -0,0 +1,11 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:p1 ex:knows2 ex:p2. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/report.ttl b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/report.ttl new file mode 100644 index 00000000000..49185f9ced7 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/invalid/case6/report.ttl @@ -0,0 +1,33 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p1; + sh:resultPath ex:knows2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:node [ a sh:NodeShape; + sh:property [ a sh:PropertyShape; + sh:path ex:knows3; + sh:property [ a sh:PropertyShape; + sh:datatype xsd:float; + sh:path ex:knows4 + ] + ] + ]; + sh:path ex:knows2 + ]; + sh:value ex:p2 + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/shacl.trig new file mode 100644 index 00000000000..e9ac07826c3 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/shacl.trig @@ -0,0 +1,29 @@ +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rdf4j: . + + { + ex:PersonShape a sh:NodeShape; + sh:targetClass ex:Person, ex:SecondTarget; + sh:property [ + sh:path ex:knows1; + sh:property [ + sh:path ex:knows2; + sh:node [ + sh:property [ + sh:path ex:knows3; + sh:property [ + sh:path ex:knows4; + sh:datatype xsd:float + ] + ] + ] + ] + ] . + rdf4j:nil sh:shapesGraph rdf4j:nil. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case1/query1.rq new file mode 100644 index 00000000000..4bb7b4132df --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case1/query1.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:Person ; + ex:knows1 [ex:knows2 [ex:knows3 [ex:knows4 "1.1"^^xsd:float]]]. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/query1.rq new file mode 100644 index 00000000000..62b8e5dbf4e --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/query1.rq @@ -0,0 +1,11 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:p1 ex:knows4 "1.1"^^xsd:float. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/query2.rq new file mode 100644 index 00000000000..4b39e525467 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/query2.rq @@ -0,0 +1,13 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:validPerson1 a ex:Person ; + ex:knows1 [ex:knows2 [ex:knows3 ex:p1]]. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/nestedNode/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query1.rq index 6788d7401bb..57c5d70a7a4 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query1.rq +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query1.rq @@ -5,6 +5,6 @@ PREFIX rdfs: PREFIX sh: PREFIX xsd: -DELETE DATA { - ex:validPerson1 ex:info "red" . +INSERT DATA { + ex:validPerson1 ex:info "blue", "red" . } diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query2.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query2.rq new file mode 100644 index 00000000000..6788d7401bb --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:validPerson1 ex:info "red" . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case4/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case4/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case4/query1.rq new file mode 100644 index 00000000000..6788d7401bb --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case4/query1.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:validPerson1 ex:info "red" . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case4/report.ttl new file mode 100644 index 00000000000..b2db3f94dfc --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case4/report.ttl @@ -0,0 +1,23 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 + ] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr2/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr2/valid/case1/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr2/valid/case1/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr2/valid/case1/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr2/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr2/valid/case2/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr2/valid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr2/valid/case2/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/maxCount/notNot/invalid/case4/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/maxCount/notNot/invalid/case4/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/maxCount/notNot/invalid/case4/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/maxCount/notNot/invalid/case4/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case1/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case1/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case1/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case2/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case2/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case3/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case3/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case3/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case4/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case4/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case4/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case4/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case5/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case5/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case5/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case5/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case1/query1.rq new file mode 100644 index 00000000000..2e90364ff92 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case1/query1.rq @@ -0,0 +1,32 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:p1 a ex:Person. +ex:p1 ex:knows1 ex:p2, ex:p22, ex:p222. + +ex:p2 ex:knows2 ex:p3, ex:p33, ex:p333. +ex:p2 ex:knows3 ex:p4, ex:p44. + +ex:p22 ex:knows2 ex:p33. +ex:p222 ex:knows2 ex:p2. + +ex:p3 ex:knows3 ex:p4, ex:p44, ex:p444. +ex:p33 ex:knows3 ex:p4, ex:p44. +ex:p333 ex:knows3 ex:p44, ex:p444. + +ex:p4 ex:knows4 _:bnode2, _:bnode3. +ex:p44 ex:knows4 _:bnode2, _:bnode3, _:bnode4. +ex:p444 ex:knows4 _:bnode2, _:bnode3. + +_:bnode4 ex:knows5 _:bnode2, _:bnode3. +_:bnode3 ex:knows5 _:bnode2, _:bnode3, _:bnode4. +_:bnode2 ex:knows5 _:bnode2, _:bnode3. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case1/report.ttl new file mode 100644 index 00000000000..976df3ca3a2 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case1/report.ttl @@ -0,0 +1,80 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode2; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:fa5cdbe46be94176b45ae82a1f1013ef11208; + sh:value _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode3; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:fa5cdbe46be94176b45ae82a1f1013ef11208; + sh:value _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode4; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:fa5cdbe46be94176b45ae82a1f1013ef11208; + sh:value _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode3; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:fa5cdbe46be94176b45ae82a1f1013ef11208; + sh:value _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode3 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode4; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:fa5cdbe46be94176b45ae82a1f1013ef11208; + sh:value _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode3 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode2; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:fa5cdbe46be94176b45ae82a1f1013ef11208; + sh:value _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode3 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode3; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:fa5cdbe46be94176b45ae82a1f1013ef11208; + sh:value _:genid-6c6ac473daf740429803e3d85c951cdb95432-bnode4 + ] . + +_:fa5cdbe46be94176b45ae82a1f1013ef11208 a sh:PropertyShape; + sh:nodeKind sh:IRI; + sh:path ex:knows5 . diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case2/query1.rq new file mode 100644 index 00000000000..f2becc436cd --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case2/query1.rq @@ -0,0 +1,31 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:p1 a ex:Person. +ex:p1 ex:knows1 ex:p2, ex:p22, ex:p222. + +ex:p2 ex:knows2 ex:p3, ex:p33, ex:p333. +ex:p2 ex:knows3 ex:p4, ex:p44. + +ex:p22 ex:knows2 ex:p33. +ex:p222 ex:knows2 ex:p2. + +ex:p3 ex:knows3 ex:p4, ex:p44, ex:p444. +ex:p33 ex:knows3 ex:p4, ex:p44. +ex:p333 ex:knows3 ex:p44, ex:p444. + +ex:p4 ex:knows4 ex:p5, ex:p55. +ex:p44 ex:knows4 ex:p5, ex:p55, ex:p555. +ex:p444 ex:knows4 ex:p5, ex:p55. + +ex:p5 ex:knows5 _:bnode2, _:bnode3. +ex:p55 ex:knows5 _:bnode2, _:bnode3, _:bnode4. +ex:p555 ex:knows5 _:bnode2, _:bnode3. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case2/report.ttl new file mode 100644 index 00000000000..ad3642b21cd --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case2/report.ttl @@ -0,0 +1,80 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p5; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:a799f05443e446b3a8e6afeb817a09a914840; + sh:value _:genid-f80a96476e0b4c59a8735fcc49f77ef718064-bnode2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p555; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:a799f05443e446b3a8e6afeb817a09a914840; + sh:value _:genid-f80a96476e0b4c59a8735fcc49f77ef718064-bnode3 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:a799f05443e446b3a8e6afeb817a09a914840; + sh:value _:genid-f80a96476e0b4c59a8735fcc49f77ef718064-bnode2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:a799f05443e446b3a8e6afeb817a09a914840; + sh:value [] + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:a799f05443e446b3a8e6afeb817a09a914840; + sh:value _:genid-f80a96476e0b4c59a8735fcc49f77ef718064-bnode3 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p555; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:a799f05443e446b3a8e6afeb817a09a914840; + sh:value _:genid-f80a96476e0b4c59a8735fcc49f77ef718064-bnode2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p5; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:a799f05443e446b3a8e6afeb817a09a914840; + sh:value _:genid-f80a96476e0b4c59a8735fcc49f77ef718064-bnode3 + ] . + +_:a799f05443e446b3a8e6afeb817a09a914840 a sh:PropertyShape; + sh:nodeKind sh:IRI; + sh:path ex:knows5 . diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case3/query1.rq new file mode 100644 index 00000000000..f5625206772 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case3/query1.rq @@ -0,0 +1,31 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:p1 a ex:Person2. +ex:p1 ex:knows1 ex:p2, ex:p22, ex:p222. + +ex:p2 ex:knows2 ex:p3, ex:p33, ex:p333. +ex:p2 ex:knows3 ex:p4, ex:p44. + +ex:p22 ex:knows2 ex:p33. +ex:p222 ex:knows2 ex:p2. + +ex:p3 ex:knows3 ex:p4, ex:p44, ex:p444. +ex:p33 ex:knows3 ex:p4, ex:p44. +ex:p333 ex:knows3 ex:p44, ex:p444. + +ex:p4 ex:knows4 ex:p5, ex:p55. +ex:p44 ex:knows4 ex:p5, ex:p55, ex:p555. +ex:p444 ex:knows4 ex:p5, ex:p55. + +ex:p5 ex:knows5 ex:invalid1, ex:invalid2. +ex:p55 ex:knows5 ex:invalid1, ex:invalid2, ex:invalid3. +ex:p555 ex:knows5 ex:invalid1, ex:invalid2. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case3/report.ttl new file mode 100644 index 00000000000..b4efd2e4c28 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case3/report.ttl @@ -0,0 +1,80 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p555; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid3 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p5; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p555; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p5; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ] . + +_:732466f613c34468a12927308efb81a914840 a sh:PropertyShape; + sh:nodeKind sh:BlankNode; + sh:path ex:knows5 . diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/query1.rq new file mode 100644 index 00000000000..8a5bb709732 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/query1.rq @@ -0,0 +1,26 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:p1 a ex:Person2. +ex:p1 ex:knows1 ex:p2, ex:p22, ex:p222. + +ex:p2 ex:knows2 ex:p3, ex:p33, ex:p333. + +ex:p22 ex:knows2 ex:p33. +ex:p222 ex:knows2 ex:p2. + +ex:p4 ex:knows4 ex:p5, ex:p55. +ex:p44 ex:knows4 ex:p5, ex:p55, ex:p555. +ex:p444 ex:knows4 ex:p5, ex:p55. + +ex:p5 ex:knows5 ex:invalid1, ex:invalid2. +ex:p55 ex:knows5 ex:invalid1, ex:invalid2, ex:invalid3. +ex:p555 ex:knows5 ex:invalid1, ex:invalid2. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/query2.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/query2.rq new file mode 100644 index 00000000000..14079d1e9da --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/query2.rq @@ -0,0 +1,15 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:p2 ex:knows3 ex:p4, ex:p44. + +ex:p3 ex:knows3 ex:p4, ex:p44, ex:p444. +ex:p33 ex:knows3 ex:p4, ex:p44. +ex:p333 ex:knows3 ex:p44, ex:p444. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/report.ttl new file mode 100644 index 00000000000..b4efd2e4c28 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case4/report.ttl @@ -0,0 +1,80 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p555; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid3 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p5; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p555; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p5; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ] . + +_:732466f613c34468a12927308efb81a914840 a sh:PropertyShape; + sh:nodeKind sh:BlankNode; + sh:path ex:knows5 . diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case5/query1.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case5/query1.rq new file mode 100644 index 00000000000..10d85f9bc45 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case5/query1.rq @@ -0,0 +1,30 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:p1 a ex:Person. +ex:p1 ex:knows1 ex:p2, ex:p22, ex:p222. + +ex:p2 ex:knows2 ex:p3, ex:p33, ex:p333. +ex:p2 ex:knows3 ex:p4, ex:p44. + +ex:p22 ex:knows2 ex:p33. +ex:p222 ex:knows2 ex:p2. + +ex:p3 ex:knows3 ex:p4, ex:p44, ex:p444. +ex:p33 ex:knows3 ex:p4, ex:p44. +ex:p333 ex:knows3 ex:p44, ex:p444. + +ex:p4 ex:knows4 _:bnode2. +ex:p44 ex:knows4 _:bnode2. +ex:p444 ex:knows4 _:bnode2. + +_:bnode2 ex:knows5 _:bnode2, _:bnode3. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case5/report.ttl b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case5/report.ttl new file mode 100644 index 00000000000..2d80b44b6fb --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case5/report.ttl @@ -0,0 +1,35 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-bb83388cb99e4e1e887ebc772122a9ca57103-bnode2; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:333910f927574097a749f6b0d7ac2bbd21356; + sh:value _:genid-bb83388cb99e4e1e887ebc772122a9ca57103-bnode2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode _:genid-bb83388cb99e4e1e887ebc772122a9ca57103-bnode2; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:333910f927574097a749f6b0d7ac2bbd21356; + sh:value [] + ] . + +_:333910f927574097a749f6b0d7ac2bbd21356 a sh:PropertyShape; + sh:nodeKind sh:IRI; + sh:path ex:knows5 . diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case6/query1.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case6/query1.rq new file mode 100644 index 00000000000..c990b4f67f7 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case6/query1.rq @@ -0,0 +1,29 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:p1 a ex:Person2. +ex:p1 ex:knows1 ex:p2, ex:p22, ex:p222. + +ex:p2 ex:knows2 ex:p3, ex:p33, ex:p333. +ex:p2 ex:knows3 ex:p4. + +ex:p22 ex:knows2 ex:p33. +ex:p222 ex:knows2 ex:p2. + +ex:p3 ex:knows3 ex:p4. +ex:p33 ex:knows3 ex:p4. +ex:p333 ex:knows3 ex:p4. + +ex:p4 ex:knows4 ex:p5, ex:p55, ex:p555. + +ex:p5 ex:knows5 ex:invalid1, ex:invalid2. +ex:p55 ex:knows5 ex:invalid1, ex:invalid2, ex:invalid3. +ex:p555 ex:knows5 ex:invalid1, ex:invalid2. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case6/report.ttl b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case6/report.ttl new file mode 100644 index 00000000000..b4efd2e4c28 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/invalid/case6/report.ttl @@ -0,0 +1,80 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p555; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid3 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p5; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid1 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p555; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p5; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ], [ a sh:ValidationResult; + rsx:dataGraph rdf4j:nil; + rsx:shapesGraph rdf4j:nil; + sh:focusNode ex:p55; + sh:resultPath ex:knows5; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NodeKindConstraintComponent; + sh:sourceShape _:732466f613c34468a12927308efb81a914840; + sh:value ex:invalid2 + ] . + +_:732466f613c34468a12927308efb81a914840 a sh:PropertyShape; + sh:nodeKind sh:BlankNode; + sh:path ex:knows5 . diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/shacl.trig new file mode 100644 index 00000000000..9a73b080955 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/shacl.trig @@ -0,0 +1,73 @@ +@prefix : . +@prefix ont: . +@prefix vocsh: . +@prefix so: . +@prefix affected: . +@prefix res: . +@prefix dct: . +@prefix gn: . +@prefix owl: . +@prefix puml: . +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . +@prefix void: . +@prefix wgs84: . +@prefix xsd: . +@prefix sh: . +@prefix dash: . +@prefix rsx: . +@prefix ec: . +@prefix ecinst: . +@prefix rdf4j: . +@prefix ex: . + + + +{ + + + ex:NodeKindCompressPropertyShapeIRI + a sh:PropertyShape ; + sh:targetClass ex:Person ; + sh:path ex:knows1 ; + sh:property [ + sh:path ex:knows2 ; + sh:property [ + sh:path ex:knows3 ; + sh:property [ + sh:path ex:knows4 ; + sh:property [ + sh:path ex:knows5 ; + sh:nodeKind sh:IRI; + + ] + ] + ] + ] + . + + ex:NodeKindCompressPropertyShapeBnode + a sh:PropertyShape ; + sh:targetClass ex:Person2 ; + sh:path ex:knows1 ; + sh:property [ + sh:path ex:knows2 ; + sh:property [ + sh:path ex:knows3 ; + sh:property [ + sh:path ex:knows4 ; + sh:property [ + sh:path ex:knows5 ; + sh:nodeKind sh:BlankNode; + + ] + ] + ] + ] + . + + + rdf4j:nil sh:shapesGraph rdf4j:nil. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case1/query1.rq new file mode 100644 index 00000000000..31e86f76b8c --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case1/query1.rq @@ -0,0 +1,17 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:p1 a ex:Person. +ex:p1 ex:knows1 ex:p2. +ex:p2 ex:knows2 ex:p3. +ex:p2 ex:knows2 ex:p33. +ex:p3 ex:knows3 ex:node1. +ex:p33 ex:knows3 ex:node1. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/query1.rq new file mode 100644 index 00000000000..efb78741e71 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/query1.rq @@ -0,0 +1,16 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:p1 a ex:Person. +ex:p2 ex:knows2 ex:p3. +ex:p2 ex:knows2 ex:p33. +ex:p3 ex:knows3 ex:node1. +ex:p33 ex:knows3 ex:node1. + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/query2.rq new file mode 100644 index 00000000000..655d1f8801a --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/query2.rq @@ -0,0 +1,13 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:p1 ex:knows1 ex:p2. + + +} + diff --git a/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/nodeKind/simpleCompress/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case1/query1.rq new file mode 100644 index 00000000000..c2c9cb98c5d --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case1/query1.rq @@ -0,0 +1,24 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person1 a ex:Person. + + ex:person1 ex:knows1 ex:person2 . + ex:person2 ex:knows2 ex:person3 . + ex:person3 ex:knows3 ex:person4 . + ex:person4 ex:knows4 ex:person5 . + ex:person5 ex:knows5 ex:person6 . + ex:person6 ex:knows6 ex:person7 . + ex:person7 ex:knows7 ex:person8 . + ex:person8 ex:knows8 ex:person9 . + ex:person9 ex:knows9 ex:person10 . + ex:person10 ex:knows10 ex:person11 . + ex:person11 rdf:type ex:NotPerson . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case1/report.ttl new file mode 100644 index 00000000000..02e72e7242e --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case1/report.ttl @@ -0,0 +1,26 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person6; + sh:resultPath _:dc6027fb6bea4bc5aa60e7ed606c2db116354; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:Person; + sh:path _:dc6027fb6bea4bc5aa60e7ed606c2db116354 + ] + ] . + +_:dc6027fb6bea4bc5aa60e7ed606c2db116354 rdf:first ex:knows6; + rdf:rest (ex:knows7 ex:knows8 ex:knows9 ex:knows10 rdf:type) . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/query1.rq new file mode 100644 index 00000000000..f93b3de9bf4 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/query1.rq @@ -0,0 +1,23 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person1 a ex:Person. + + ex:person1 ex:knows1 ex:person2 . + ex:person2 ex:knows2 ex:person3 . + ex:person3 ex:knows3 ex:person4 . + ex:person4 ex:knows4 ex:person5 . + ex:person5 ex:knows5 ex:person6 . + ex:person6 ex:knows6 ex:person7 . + ex:person7 ex:knows7 ex:person8 . + ex:person8 ex:knows8 ex:person9 . + ex:person9 ex:knows9 ex:person10 . + ex:person10 ex:knows10 ex:person11 . + ex:person11 rdf:type ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/query2.rq new file mode 100644 index 00000000000..ebd96286f23 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person8 ex:knows8 ex:person9 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/report.ttl new file mode 100644 index 00000000000..69338383780 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case2/report.ttl @@ -0,0 +1,26 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person6; + sh:resultPath _:dc6027fb6bea4bc5aa60e7ed606c2db116373; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:Person; + sh:path _:dc6027fb6bea4bc5aa60e7ed606c2db116373 + ] + ] . + +_:dc6027fb6bea4bc5aa60e7ed606c2db116373 rdf:first ex:knows6; + rdf:rest (ex:knows7 ex:knows8 ex:knows9 ex:knows10 rdf:type) . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/query1.rq new file mode 100644 index 00000000000..d47ac31b3c6 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/query1.rq @@ -0,0 +1,23 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person1 a ex:Person. + + ex:person1 ex:knows1 ex:person2 . + ex:person2 ex:knows2 ex:person3 . + ex:person3 ex:knows3 ex:person4 . + + ex:person5 ex:knows5 ex:person6 . + ex:person6 ex:knows6 ex:person7 . + ex:person7 ex:knows7 ex:person8 . + ex:person8 ex:knows8 ex:person9 . + ex:person9 ex:knows9 ex:person10 . + ex:person10 ex:knows10 ex:person11 . + ex:person11 rdf:type ex:NotAPerson . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/query2.rq new file mode 100644 index 00000000000..d89a6c2e2e4 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/query2.rq @@ -0,0 +1,23 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE { + ex:person9 ex:knows9 ex:person10 . + +} + +INSERT { + ex:person4 ex:knows4 ex:person5 . + +} + +WHERE { + +?a ?b ?c. +} + + diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/report.ttl new file mode 100644 index 00000000000..6f9c546753f --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/invalid/case3/report.ttl @@ -0,0 +1,26 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person6; + sh:resultPath _:8957fac2895740b4917680a91e95267516420; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:Person; + sh:path _:8957fac2895740b4917680a91e95267516420 + ] + ] . + +_:8957fac2895740b4917680a91e95267516420 rdf:first ex:knows6; + rdf:rest (ex:knows7 ex:knows8 ex:knows9 ex:knows10 rdf:type) . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/shacl.trig new file mode 100644 index 00000000000..6e9639c521c --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/shacl.trig @@ -0,0 +1,20 @@ +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rdf4j: . + +rdf4j:SHACLShapeGraph { + ex:PersonShape a sh:NodeShape; + sh:targetClass ex:Person; + sh:property [ + sh:path (ex:knows1 ex:knows2 ex:knows3 ex:knows4 ex:knows5 ); + sh:property [ + sh:path (ex:knows6 ex:knows7 ex:knows8 ex:knows9 ex:knows10 rdf:type); + sh:hasValue ex:Person + ] + ] . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case1/query1.rq new file mode 100644 index 00000000000..a0357843e54 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case1/query1.rq @@ -0,0 +1,22 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person1 ex:knows1 ex:person2 . + ex:person2 ex:knows2 ex:person3 . + ex:person3 ex:knows3 ex:person4 . + ex:person4 ex:knows4 ex:person5 . + ex:person5 ex:knows5 ex:person6 . + ex:person6 ex:knows6 ex:person7 . + ex:person7 ex:knows7 ex:person8 . + ex:person8 ex:knows8 ex:person9 . + ex:person9 ex:knows9 ex:person10 . + ex:person10 ex:knows10 ex:person11 . + ex:person11 rdf:type ex:Person . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/query1.rq new file mode 100644 index 00000000000..c35b1423f83 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/query1.rq @@ -0,0 +1,21 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person1 ex:knows1 ex:person2 . + ex:person2 ex:knows2 ex:person3 . + ex:person3 ex:knows3 ex:person4 . + ex:person4 ex:knows4 ex:person5 . + ex:person5 ex:knows5 ex:person6 . + ex:person6 ex:knows6 ex:person7 . + ex:person8 ex:knows8 ex:person9 . + ex:person9 ex:knows9 ex:person10 . + ex:person10 ex:knows10 ex:person11 . + ex:person11 rdf:type ex:Person . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/query2.rq new file mode 100644 index 00000000000..233c388990e --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person7 ex:knows7 ex:person8 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePath2/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case1/query1.rq new file mode 100644 index 00000000000..47231297172 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case1/query1.rq @@ -0,0 +1,17 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + ex:person1 ex:knows [ex:knows ex:peter]. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case1/report.ttl new file mode 100644 index 00000000000..1397a76414d --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case1/report.ttl @@ -0,0 +1,40 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:c1559dfa8ea34564af0ca11efbae9a1416378; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:ClassConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:class ex:Person; + sh:path _:c1559dfa8ea34564af0ca11efbae9a1416378 + ]; + sh:value ex:peter + ], [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:c1559dfa8ea34564af0ca11efbae9a1416381; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:Person; + sh:path _:c1559dfa8ea34564af0ca11efbae9a1416381 + ] + ] . + +_:c1559dfa8ea34564af0ca11efbae9a1416378 rdf:first ex:knows; + rdf:rest (ex:knows) . + +_:c1559dfa8ea34564af0ca11efbae9a1416381 rdf:first ex:knows; + rdf:rest (ex:knows rdf:type) . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query1.rq new file mode 100644 index 00000000000..a0d4d35df24 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query1.rq @@ -0,0 +1,20 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query2.rq new file mode 100644 index 00000000000..59f53e614bf --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query2.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person3 ex:knows3 ex:person4. + ex:peter a ex:Person . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query3.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query3.rq new file mode 100644 index 00000000000..bac764e2fa5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/query3.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person3 ex:knows3 ex:person4. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/report.ttl new file mode 100644 index 00000000000..1397a76414d --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case2/report.ttl @@ -0,0 +1,40 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:c1559dfa8ea34564af0ca11efbae9a1416378; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:ClassConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:class ex:Person; + sh:path _:c1559dfa8ea34564af0ca11efbae9a1416378 + ]; + sh:value ex:peter + ], [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:c1559dfa8ea34564af0ca11efbae9a1416381; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:Person; + sh:path _:c1559dfa8ea34564af0ca11efbae9a1416381 + ] + ] . + +_:c1559dfa8ea34564af0ca11efbae9a1416378 rdf:first ex:knows; + rdf:rest (ex:knows) . + +_:c1559dfa8ea34564af0ca11efbae9a1416381 rdf:first ex:knows; + rdf:rest (ex:knows rdf:type) . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/query1.rq new file mode 100644 index 00000000000..aa354b4c474 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/query1.rq @@ -0,0 +1,20 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows ex:steve. + ex:steve ex:knows ex:peter. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/query2.rq new file mode 100644 index 00000000000..2fc53f9e702 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person1 ex:knows ex:steve. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/report.ttl new file mode 100644 index 00000000000..0d1c5872194 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case3/report.ttl @@ -0,0 +1,26 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:9cc6828666734d6692c632592ba0f13c6114; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:Person; + sh:path _:9cc6828666734d6692c632592ba0f13c6114 + ] + ] . + +_:9cc6828666734d6692c632592ba0f13c6114 rdf:first ex:knows; + rdf:rest (ex:knows rdf:type) . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/query1.rq new file mode 100644 index 00000000000..aa354b4c474 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/query1.rq @@ -0,0 +1,20 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows ex:steve. + ex:steve ex:knows ex:peter. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/query2.rq new file mode 100644 index 00000000000..9f65c203dc1 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:steve ex:knows ex:peter. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/report.ttl new file mode 100644 index 00000000000..0d1c5872194 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/invalid/case4/report.ttl @@ -0,0 +1,26 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:9cc6828666734d6692c632592ba0f13c6114; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:Person; + sh:path _:9cc6828666734d6692c632592ba0f13c6114 + ] + ] . + +_:9cc6828666734d6692c632592ba0f13c6114 rdf:first ex:knows; + rdf:rest (ex:knows rdf:type) . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/shacl.trig new file mode 100644 index 00000000000..28f7e225b16 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/shacl.trig @@ -0,0 +1,23 @@ +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rdf4j: . +@prefix rsx: . + + +rdf4j:SHACLShapeGraph { + ex:PersonShape a sh:NodeShape; + rsx:targetShape [ sh:path (ex:knows1 ex:knows2 ex:knows3 ex:knows4 ex:knows5 rdf:type); sh:hasValue ex:Person ]; + sh:property [ + sh:path (ex:knows ex:knows); + sh:class ex:Person + ] , + [ + sh:path (ex:knows ex:knows rdf:type); + sh:hasValue ex:Person + ] . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case1/query1.rq new file mode 100644 index 00000000000..f9f2cf08e17 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case1/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/query1.rq new file mode 100644 index 00000000000..71ebbf6056d --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/query1.rq @@ -0,0 +1,18 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/query2.rq new file mode 100644 index 00000000000..81ef24e4d58 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/query2.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person6 rdf:type ex:Person. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/query1.rq new file mode 100644 index 00000000000..f9f2cf08e17 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/query2.rq new file mode 100644 index 00000000000..f4bf58cf8db --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/query2.rq @@ -0,0 +1,15 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case3/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/query1.rq new file mode 100644 index 00000000000..f9f2cf08e17 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/query2.rq new file mode 100644 index 00000000000..0d8b055908d --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person1 ex:knows1 ex:person2. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case4/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/query1.rq new file mode 100644 index 00000000000..f9f2cf08e17 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/query2.rq new file mode 100644 index 00000000000..324da579200 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person6 rdf:type ex:Person. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape1/valid/case5/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/shacl.trig new file mode 100644 index 00000000000..6d6fc34e39c --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/shacl.trig @@ -0,0 +1,29 @@ +@prefix dash: . +@prefix ex: . +@prefix rdf4j: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix sh: . +@prefix xsd: . + + +rdf4j:SHACLShapeGraph { + + +ex:shape1 a sh:NodeShape ; + rsx:targetShape [ + sh:property [ + sh:path rdf:type ; + sh:hasValue ex:Type1 ; + ], [ + sh:path ( ex:knows rdf:type ) ; + sh:hasValue ex:Type2 ; + ] ; + ] ; + + sh:property [ + sh:path ex:trueProp ; + sh:hasValue true ; + ]. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/query1.rq new file mode 100644 index 00000000000..79f86a7a7d1 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/query1.rq @@ -0,0 +1,15 @@ +PREFIX dash: +PREFIX ex: +PREFIX rdf4j: +PREFIX rdf: +PREFIX rdfs: +PREFIX rsx: +PREFIX sh: +PREFIX xsd: + + +INSERT DATA { + ex:validNode ex:knows ex:node2 . + ex:node2 rdf:type ex:Type1 ; + rdf:type ex:Type2 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/query2.rq new file mode 100644 index 00000000000..e25912e9e5f --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/query2.rq @@ -0,0 +1,12 @@ +PREFIX dash: +PREFIX ex: +PREFIX rdf4j: +PREFIX rdf: +PREFIX rdfs: +PREFIX rsx: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:node2 rdf:type ex:Type2 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case2/query1.rq new file mode 100644 index 00000000000..0222c9b4562 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case2/query1.rq @@ -0,0 +1,16 @@ +PREFIX dash: +PREFIX ex: +PREFIX rdf4j: +PREFIX rdf: +PREFIX rdfs: +PREFIX rsx: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:validNode1 a ex:Type1 . + ex:validNode1 ex:trueProp true . + ex:validNode1 ex:knows ex:validNode2 . + + ex:validNode2 rdf:type ex:Type2 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/initialData.trig b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/initialData.trig new file mode 100644 index 00000000000..ccd28689cd2 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/initialData.trig @@ -0,0 +1,15 @@ +@prefix dash: . +@prefix ex: . +@prefix rdf4j: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix sh: . +@prefix xsd: . + + + + ex:validNode ex:knows ex:node2 . + ex:node2 rdf:type ex:Type1 ; + rdf:type ex:Type2 . + diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/query1.rq new file mode 100644 index 00000000000..e25912e9e5f --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/query1.rq @@ -0,0 +1,12 @@ +PREFIX dash: +PREFIX ex: +PREFIX rdf4j: +PREFIX rdf: +PREFIX rdfs: +PREFIX rsx: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:node2 rdf:type ex:Type2 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape2/valid/case3/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case1/query1.rq new file mode 100644 index 00000000000..4476dd8e93b --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case1/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 a ex:Person. + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:NotPerson . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case1/report.ttl new file mode 100644 index 00000000000..903364fefbe --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case1/report.ttl @@ -0,0 +1,64 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:c14bfc459ea04babae502c7b0cdc3a9c16977; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NotConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:not [ a sh:NodeShape; + sh:hasValue ex:NotPerson + ]; + sh:path _:c14bfc459ea04babae502c7b0cdc3a9c16977 + ]; + sh:value ex:NotPerson + ], [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath ex:test; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:yay; + sh:path ex:test + ] + ], [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:c14bfc459ea04babae502c7b0cdc3a9c16985; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:NotPerson; + sh:path _:c14bfc459ea04babae502c7b0cdc3a9c16985 + ] + ], [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:c14bfc459ea04babae502c7b0cdc3a9c16988; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:HasValueConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:hasValue ex:person1; + sh:path _:c14bfc459ea04babae502c7b0cdc3a9c16988 + ] + ] . + +_:c14bfc459ea04babae502c7b0cdc3a9c16977 rdf:first ex:knows; + rdf:rest (ex:knows rdf:type) . + +_:c14bfc459ea04babae502c7b0cdc3a9c16985 rdf:first ex:test; + rdf:rest (rdf:type) . + +_:c14bfc459ea04babae502c7b0cdc3a9c16988 sh:inversePath ex:knows1 . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query1.rq new file mode 100644 index 00000000000..a1e821ace42 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query1.rq @@ -0,0 +1,24 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 a ex:Person. + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + ex:person1 ex:test ex:yay. + ex:yay a ex:NotPerson. + ex:person1 ex:knows1 ex:person1. + + ex:person1 ex:knows [ex:knows ex:peter]. + + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query2.rq new file mode 100644 index 00000000000..59f53e614bf --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query2.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person3 ex:knows3 ex:person4. + ex:peter a ex:Person . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query3.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query3.rq new file mode 100644 index 00000000000..287b888d1ef --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/query3.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person3 ex:knows3 ex:person4. + ex:peter a ex:NotPerson . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/report.ttl new file mode 100644 index 00000000000..d44735b2797 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/invalid/case2/report.ttl @@ -0,0 +1,29 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:person1; + sh:resultPath _:786feb3f7a5141ef885d37038c6d72dc6527; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:NotConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:not [ a sh:NodeShape; + sh:hasValue ex:NotPerson + ]; + sh:path _:786feb3f7a5141ef885d37038c6d72dc6527 + ]; + sh:value ex:NotPerson + ] . + +_:786feb3f7a5141ef885d37038c6d72dc6527 rdf:first ex:knows; + rdf:rest (ex:knows rdf:type) . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/shacl.trig new file mode 100644 index 00000000000..6601e29b661 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/shacl.trig @@ -0,0 +1,54 @@ +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rdf4j: . +@prefix rsx: . +@prefix dash: . + + +rdf4j:SHACLShapeGraph { + ex:PersonShape a sh:NodeShape; + rsx:targetShape [ + sh:property [ + sh:path rdf:type ; + sh:hasValue ex:Person ; + ]; + sh:property [ + sh:path (ex:knows1 ex:knows2 ex:knows3 ex:knows4 ex:knows5 rdf:type); + sh:hasValue ex:Person + ]; + sh:property [ + sh:path (ex:knows1 ex:knows2 ex:knows3 ex:knows4 ); + dash:hasValueIn (ex:person1 ex:person2 ex:person3 ex:person4 ex:person5 ex:person6) + ]; + + ]; + sh:property [ + sh:path (ex:knows ex:knows rdf:type); + sh:not [sh:hasValue ex:NotPerson] + ] ; + + sh:property [ + sh:path ex:test; + sh:hasValue ex:yay + ] ; + + sh:property [ + sh:path ex:test; + sh:not [sh:hasValue ex:nay] + ] ; + + sh:property [ + sh:path (ex:test rdf:type); + sh:hasValue ex:NotPerson + ] ; + + sh:property [ + sh:path [sh:inversePath ex:knows1]; + sh:hasValue ex:person1 + ] . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case1/query1.rq new file mode 100644 index 00000000000..f9f2cf08e17 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case1/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/query1.rq new file mode 100644 index 00000000000..71ebbf6056d --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/query1.rq @@ -0,0 +1,18 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/query2.rq new file mode 100644 index 00000000000..81ef24e4d58 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/query2.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person6 rdf:type ex:Person. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/query1.rq new file mode 100644 index 00000000000..f9f2cf08e17 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/query2.rq new file mode 100644 index 00000000000..f4bf58cf8db --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/query2.rq @@ -0,0 +1,15 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case3/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/query1.rq new file mode 100644 index 00000000000..f9f2cf08e17 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/query2.rq new file mode 100644 index 00000000000..0d8b055908d --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person1 ex:knows1 ex:person2. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case4/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/query1.rq new file mode 100644 index 00000000000..f9f2cf08e17 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/query2.rq new file mode 100644 index 00000000000..324da579200 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/query2.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:person6 rdf:type ex:Person. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case5/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/query1.rq new file mode 100644 index 00000000000..6d11f0f656e --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:person1 ex:knows1 ex:person2_a. + ex:person2_a ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person. + + + ex:person1 ex:knows [ex:knows ex:peter]. + ex:peter a ex:NotPerson . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/query2.rq new file mode 100644 index 00000000000..d471acc9523 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/query2.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + + ex:person3 ex:knows3 ex:person4. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case6/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/query1.rq new file mode 100644 index 00000000000..2bf318ea994 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person, ex:NotPerson. + + + ex:person1 ex:knowsA ex:peter. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/query2.rq new file mode 100644 index 00000000000..6b25667267b --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/query2.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + + ex:person6 rdf:type ex:Person. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case7/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/query1.rq new file mode 100644 index 00000000000..2bf318ea994 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/query1.rq @@ -0,0 +1,19 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + + ex:person1 ex:knows1 ex:person2. + ex:person2 ex:knows2 ex:person3. + ex:person3 ex:knows3 ex:person4. + ex:person4 ex:knows4 ex:person5. + ex:person5 ex:knows5 ex:person6. + ex:person6 rdf:type ex:Person, ex:NotPerson. + + + ex:person1 ex:knowsA ex:peter. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/query2.rq new file mode 100644 index 00000000000..fe08b6e8e75 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/query2.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + + ex:person5 ex:knows5 ex:person6. + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShape3/valid/case8/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/shacl.trig new file mode 100644 index 00000000000..4c3480caa42 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/shacl.trig @@ -0,0 +1,29 @@ +@prefix dash: . +@prefix ex: . +@prefix rdf4j: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix sh: . +@prefix xsd: . + + +rdf4j:SHACLShapeGraph { + + +ex:shape1 a sh:NodeShape ; + rsx:targetShape [ + sh:property [ + sh:path rdf:type ; + sh:hasValue ex:Type1 ; + ], [ + sh:path ( ex:knows rdf:type ) ; + sh:hasValue ex:Type2 ; + ] ; + ] ; + + sh:property [ + sh:path ex:trueProp ; + sh:not [sh:hasValue false] ; + ]. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/query1.rq new file mode 100644 index 00000000000..79f86a7a7d1 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/query1.rq @@ -0,0 +1,15 @@ +PREFIX dash: +PREFIX ex: +PREFIX rdf4j: +PREFIX rdf: +PREFIX rdfs: +PREFIX rsx: +PREFIX sh: +PREFIX xsd: + + +INSERT DATA { + ex:validNode ex:knows ex:node2 . + ex:node2 rdf:type ex:Type1 ; + rdf:type ex:Type2 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/query2.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/query2.rq new file mode 100644 index 00000000000..e25912e9e5f --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/query2.rq @@ -0,0 +1,12 @@ +PREFIX dash: +PREFIX ex: +PREFIX rdf4j: +PREFIX rdf: +PREFIX rdfs: +PREFIX rsx: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:node2 rdf:type ex:Type2 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case2/query1.rq new file mode 100644 index 00000000000..0222c9b4562 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case2/query1.rq @@ -0,0 +1,16 @@ +PREFIX dash: +PREFIX ex: +PREFIX rdf4j: +PREFIX rdf: +PREFIX rdfs: +PREFIX rsx: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:validNode1 a ex:Type1 . + ex:validNode1 ex:trueProp true . + ex:validNode1 ex:knows ex:validNode2 . + + ex:validNode2 rdf:type ex:Type2 . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/path/sequencePathTargetShapeNot/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/qualifiedShape/maxCountSimple/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/qualifiedShape/maxCountSimple/invalid/case3/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/qualifiedShape/maxCountSimple/invalid/case3/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/qualifiedShape/maxCountSimple/invalid/case3/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/qualifiedShape/maxCountSimple/invalid/case4/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/qualifiedShape/maxCountSimple/invalid/case4/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/qualifiedShape/maxCountSimple/invalid/case4/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/qualifiedShape/maxCountSimple/invalid/case4/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/qualifiedShape/minCountSimple/invalid/case5/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/qualifiedShape/minCountSimple/invalid/case5/initialData.trig similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/qualifiedShape/minCountSimple/invalid/case5/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/qualifiedShape/minCountSimple/invalid/case5/initialData.trig diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case1/query1.rq new file mode 100644 index 00000000000..ccfa5521b0e --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case1/query1.rq @@ -0,0 +1,14 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:ValidCountry a ex:Country ; + ex:germanLabel "Spanien"@de . + +ex:InvalidCountry a ex:Country ; + ex:germanLabel "Spain"@en . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case1/report.ttl new file mode 100644 index 00000000000..6626e1eaeff --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case1/report.ttl @@ -0,0 +1,46 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:InvalidCountry; + sh:resultMessage "Values are literals with German language tag."; + sh:resultSeverity sh:Violation; + sh:sourceConstraint _:5089a376325a403b926b5c31d5e95e7218012; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent; + sh:sourceShape ex:LanguageExampleShape; + sh:value ex:InvalidCountry + ] . + +ex:LanguageExampleShape a sh:NodeShape; + sh:sparql _:5089a376325a403b926b5c31d5e95e7218012; + sh:targetClass ex:Country . + +_:5089a376325a403b926b5c31d5e95e7218012 a sh:SPARQLConstraint; + sh:deactivated false; + sh:message "Values are literals with German language tag."; + sh:prefixes ; + sh:select """ + SELECT ?this + WHERE { + $this ex:germanLabel ?value . + FILTER (isLiteral(?value) && !langMatches(lang(?value), \"de\")) + } + """ . + + sh:declare [ + sh:namespace "http://example.com/ns#"^^xsd:anyURI; + sh:prefix "ex" + ], [ + sh:namespace "http://schema.org/"^^xsd:anyURI; + sh:prefix "schema" + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/query1.rq new file mode 100644 index 00000000000..4da878976ec --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/query1.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:InvalidCountry ex:germanLabel "Spain"@en . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/query2.rq new file mode 100644 index 00000000000..1c82510cff8 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/query2.rq @@ -0,0 +1,13 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:ValidCountry a ex:Country ; + ex:germanLabel "Spanien"@de . + +ex:InvalidCountry a ex:Country . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/report.ttl new file mode 100644 index 00000000000..7568a39b4af --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/invalid/case2/report.ttl @@ -0,0 +1,46 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:InvalidCountry; + sh:resultMessage "Values are literals with German language tag."; + sh:resultSeverity sh:Violation; + sh:sourceConstraint _:5089a376325a403b926b5c31d5e95e7218023; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent; + sh:sourceShape ex:LanguageExampleShape; + sh:value ex:InvalidCountry + ] . + +ex:LanguageExampleShape a sh:NodeShape; + sh:sparql _:5089a376325a403b926b5c31d5e95e7218023; + sh:targetClass ex:Country . + +_:5089a376325a403b926b5c31d5e95e7218023 a sh:SPARQLConstraint; + sh:deactivated false; + sh:message "Values are literals with German language tag."; + sh:prefixes ; + sh:select """ + SELECT ?this + WHERE { + $this ex:germanLabel ?value . + FILTER (isLiteral(?value) && !langMatches(lang(?value), \"de\")) + } + """ . + + sh:declare [ + sh:namespace "http://example.com/ns#"^^xsd:anyURI; + sh:prefix "ex" + ], [ + sh:namespace "http://schema.org/"^^xsd:anyURI; + sh:prefix "schema" + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/shacl.trig new file mode 100644 index 00000000000..b121fc44b22 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/shacl.trig @@ -0,0 +1,53 @@ +@prefix : . +@prefix ont: . +@prefix vocsh: . +@prefix so: . +@prefix affected: . +@prefix res: . +@prefix dct: . +@prefix gn: . +@prefix owl: . +@prefix puml: . +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . +@prefix void: . +@prefix wgs84: . +@prefix xsd: . +@prefix sh: . +@prefix dash: . +@prefix rsx: . +@prefix ec: . +@prefix ecinst: . +@prefix rdf4j: . +@prefix ex: . + +rdf4j:SHACLShapeGraph { + +ex: + sh:declare [ + sh:prefix "ex" ; + sh:namespace "http://example.com/ns#"^^xsd:anyURI ; + ] ; + sh:declare [ + sh:prefix "schema" ; + sh:namespace "http://schema.org/"^^xsd:anyURI ; + ] . + + ex:LanguageExampleShape + a sh:NodeShape ; + sh:targetClass ex:Country ; + sh:sparql [ + a sh:SPARQLConstraint ; # This triple is optional + sh:message "Values are literals with German language tag." ; + sh:prefixes ex: ; + sh:deactivated false ; + sh:select """ + SELECT ?this + WHERE { + $this ex:germanLabel ?value . + FILTER (isLiteral(?value) && !langMatches(lang(?value), "de")) + } + """ ; + ] . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case1/query1.rq new file mode 100644 index 00000000000..93cd8becf3a --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case1/query1.rq @@ -0,0 +1,28 @@ +PREFIX ex: +PREFIX : +PREFIX affected: +PREFIX dash: +PREFIX dct: +PREFIX fn: +PREFIX gn: +PREFIX ont: +PREFIX owl: +PREFIX puml: +PREFIX rdf: +PREFIX rdfs: +PREFIX res: +PREFIX sesame: +PREFIX sh: +PREFIX skos: +PREFIX so: +PREFIX vocsh: +PREFIX void: +PREFIX wgs: +PREFIX xsd: + +INSERT DATA { + +ex:ValidCountry a ex:Country ; + ex:germanLabel "Spanien"@de . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case2/query1.rq new file mode 100644 index 00000000000..fa058a146a2 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case2/query1.rq @@ -0,0 +1,32 @@ +PREFIX ex: +PREFIX : +PREFIX affected: +PREFIX dash: +PREFIX dct: +PREFIX fn: +PREFIX gn: +PREFIX ont: +PREFIX owl: +PREFIX puml: +PREFIX rdf: +PREFIX rdfs: +PREFIX res: +PREFIX sesame: +PREFIX sh: +PREFIX skos: +PREFIX so: +PREFIX vocsh: +PREFIX void: +PREFIX wgs: +PREFIX xsd: + +INSERT DATA { + + +ex:ValidCountry a ex:Country ; + ex:germanLabel "Spain"@de . + +ex:InvalidCountry a ex:Country ; + ex:germanLabel [], ex:a . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsNodeShapeNoValue/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case1/query1.rq new file mode 100644 index 00000000000..ccfa5521b0e --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case1/query1.rq @@ -0,0 +1,14 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:ValidCountry a ex:Country ; + ex:germanLabel "Spanien"@de . + +ex:InvalidCountry a ex:Country ; + ex:germanLabel "Spain"@en . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case1/report.ttl new file mode 100644 index 00000000000..c720586c8e9 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case1/report.ttl @@ -0,0 +1,46 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:InvalidCountry; + sh:resultMessage "Values are literals with German language tag."; + sh:resultPath ex:germanLabel; + sh:resultSeverity sh:Violation; + sh:sourceConstraint _:5089a376325a403b926b5c31d5e95e7218178; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent; + sh:sourceShape ex:LanguageExamplePropertyShape; + ] . + +ex:LanguageExamplePropertyShape a sh:PropertyShape; + sh:path ex:germanLabel; + sh:sparql _:5089a376325a403b926b5c31d5e95e7218178; + sh:targetClass ex:Country . + +_:5089a376325a403b926b5c31d5e95e7218178 a sh:SPARQLConstraint; + sh:message "Values are literals with German language tag."; + sh:prefixes ; + sh:select """ + SELECT $this + WHERE { + $this $PATH ?temp . + FILTER (isLiteral(?temp) && !langMatches(lang(?temp), \"de\")) + } + """ . + + sh:declare [ + sh:namespace "http://example.com/ns#"^^xsd:anyURI; + sh:prefix "ex" + ], [ + sh:namespace "http://schema.org/"^^xsd:anyURI; + sh:prefix "schema" + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/query1.rq new file mode 100644 index 00000000000..4da878976ec --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/query1.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:InvalidCountry ex:germanLabel "Spain"@en . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/query2.rq new file mode 100644 index 00000000000..1c82510cff8 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/query2.rq @@ -0,0 +1,13 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { +ex:ValidCountry a ex:Country ; + ex:germanLabel "Spanien"@de . + +ex:InvalidCountry a ex:Country . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/report.ttl new file mode 100644 index 00000000000..99ef607b7ff --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/invalid/case2/report.ttl @@ -0,0 +1,46 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + rsx:shapesGraph rdf4j:SHACLShapeGraph; + sh:focusNode ex:InvalidCountry; + sh:resultMessage "Values are literals with German language tag."; + sh:resultPath ex:germanLabel; + sh:resultSeverity sh:Violation; + sh:sourceConstraint _:5089a376325a403b926b5c31d5e95e7218429; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent; + sh:sourceShape ex:LanguageExamplePropertyShape; + ] . + +ex:LanguageExamplePropertyShape a sh:PropertyShape; + sh:path ex:germanLabel; + sh:sparql _:5089a376325a403b926b5c31d5e95e7218429; + sh:targetClass ex:Country . + +_:5089a376325a403b926b5c31d5e95e7218429 a sh:SPARQLConstraint; + sh:message "Values are literals with German language tag."; + sh:prefixes ; + sh:select """ + SELECT $this + WHERE { + $this $PATH ?temp . + FILTER (isLiteral(?temp) && !langMatches(lang(?temp), \"de\")) + } + """ . + + sh:declare [ + sh:namespace "http://example.com/ns#"^^xsd:anyURI; + sh:prefix "ex" + ], [ + sh:namespace "http://schema.org/"^^xsd:anyURI; + sh:prefix "schema" + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/shacl.trig b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/shacl.trig new file mode 100644 index 00000000000..88f7855a8cb --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/shacl.trig @@ -0,0 +1,53 @@ +@prefix : . +@prefix ont: . +@prefix vocsh: . +@prefix so: . +@prefix affected: . +@prefix res: . +@prefix dct: . +@prefix gn: . +@prefix owl: . +@prefix puml: . +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . +@prefix void: . +@prefix wgs84: . +@prefix xsd: . +@prefix sh: . +@prefix dash: . +@prefix rsx: . +@prefix ec: . +@prefix ecinst: . +@prefix rdf4j: . +@prefix ex: . + +rdf4j:SHACLShapeGraph { + +ex: + sh:declare [ + sh:prefix "ex" ; + sh:namespace "http://example.com/ns#"^^xsd:anyURI ; + ] ; + sh:declare [ + sh:prefix "schema" ; + sh:namespace "http://schema.org/"^^xsd:anyURI ; + ] . + + ex:LanguageExamplePropertyShape + a sh:PropertyShape ; + sh:targetClass ex:Country ; + sh:path ex:germanLabel ; + sh:sparql [ + a sh:SPARQLConstraint ; # This triple is optional + sh:message "Values are literals with German language tag." ; + sh:prefixes ex: ; + sh:select """ + SELECT $this + WHERE { + $this $PATH ?temp . + FILTER (isLiteral(?temp) && !langMatches(lang(?temp), "de")) + } + """ ; + ] . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case1/query1.rq new file mode 100644 index 00000000000..93cd8becf3a --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case1/query1.rq @@ -0,0 +1,28 @@ +PREFIX ex: +PREFIX : +PREFIX affected: +PREFIX dash: +PREFIX dct: +PREFIX fn: +PREFIX gn: +PREFIX ont: +PREFIX owl: +PREFIX puml: +PREFIX rdf: +PREFIX rdfs: +PREFIX res: +PREFIX sesame: +PREFIX sh: +PREFIX skos: +PREFIX so: +PREFIX vocsh: +PREFIX void: +PREFIX wgs: +PREFIX xsd: + +INSERT DATA { + +ex:ValidCountry a ex:Country ; + ex:germanLabel "Spanien"@de . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case1/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case1/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case2/query1.rq new file mode 100644 index 00000000000..fa058a146a2 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case2/query1.rq @@ -0,0 +1,32 @@ +PREFIX ex: +PREFIX : +PREFIX affected: +PREFIX dash: +PREFIX dct: +PREFIX fn: +PREFIX gn: +PREFIX ont: +PREFIX owl: +PREFIX puml: +PREFIX rdf: +PREFIX rdfs: +PREFIX res: +PREFIX sesame: +PREFIX sh: +PREFIX skos: +PREFIX so: +PREFIX vocsh: +PREFIX void: +PREFIX wgs: +PREFIX xsd: + +INSERT DATA { + + +ex:ValidCountry a ex:Country ; + ex:germanLabel "Spain"@de . + +ex:InvalidCountry a ex:Country ; + ex:germanLabel [], ex:a . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case2/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case2/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case3/query1.rq new file mode 100644 index 00000000000..9fccdddff1e --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case3/query1.rq @@ -0,0 +1,28 @@ +PREFIX ex: +PREFIX : +PREFIX affected: +PREFIX dash: +PREFIX dct: +PREFIX fn: +PREFIX gn: +PREFIX ont: +PREFIX owl: +PREFIX puml: +PREFIX rdf: +PREFIX rdfs: +PREFIX res: +PREFIX sesame: +PREFIX sh: +PREFIX skos: +PREFIX so: +PREFIX vocsh: +PREFIX void: +PREFIX wgs: +PREFIX xsd: + +INSERT DATA { + +ex:ValidCountry a ex:Country ; + ex:notGermanLabel "Spain"@en . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case3/report.ttl new file mode 100644 index 00000000000..c0518dc88b5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/sparql/constraintsPropertyShapeNoValue/valid/case3/report.ttl @@ -0,0 +1,12 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . +@prefix rdf4j: . + +[] a sh:ValidationReport; + rdf4j:truncated false; + sh:conforms true . diff --git a/core/sail/solr/pom.xml b/core/sail/solr/pom.xml index 49710681605..7d26cafd3f6 100644 --- a/core/sail/solr/pom.xml +++ b/core/sail/solr/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-sail - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-sail-solr RDF4J: Solr Sail Index @@ -12,8 +12,29 @@ false + + 3.7.2 + + 1.1.10.5 + + + org.apache.zookeeper + zookeeper + ${zookeeper.version} + + + org.apache.zookeeper + zookeeper-jute + ${zookeeper.version} + + + + org.xerial.snappy + snappy-java + ${snappy.version} + ${project.groupId} rdf4j-sail-lucene-api diff --git a/core/sparqlbuilder/pom.xml b/core/sparqlbuilder/pom.xml index 8d958714bb7..743faede34a 100644 --- a/core/sparqlbuilder/pom.xml +++ b/core/sparqlbuilder/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-sparqlbuilder RDF4J: SparqlBuilder diff --git a/core/spin/pom.xml b/core/spin/pom.xml index a7b35e1a460..cd6e4901b0e 100644 --- a/core/spin/pom.xml +++ b/core/spin/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-spin RDF4J: SPIN diff --git a/core/storage/pom.xml b/core/storage/pom.xml index d251b11ce21..ff776744e88 100644 --- a/core/storage/pom.xml +++ b/core/storage/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-core - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-storage RDF4J: Storage Libraries diff --git a/examples/pom.xml b/examples/pom.xml index 5da5d463e23..5ea69b06efe 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -7,7 +7,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index c0a9fbe818c..d9ed1fcd49e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT pom Eclipse RDF4J An extensible Java framework for RDF and SPARQL @@ -371,12 +371,13 @@ 8.9.0 8.9.0 7.15.2 - 5.3.30 + 5.3.37 32.1.3-jre 1.37 3.1.0 5.9.3 9.4.54.v20240208 + 4.1.111.Final @@ -396,6 +397,13 @@ pom import + + io.netty + netty-bom + ${netty.version} + pom + import + @@ -423,7 +431,7 @@ commons-io commons-io - 2.11.0 + 2.14.0 commons-codec diff --git a/scripts/milestone-release.sh b/scripts/milestone-release.sh index 54a0c4c6bec..28830823be2 100755 --- a/scripts/milestone-release.sh +++ b/scripts/milestone-release.sh @@ -208,11 +208,11 @@ mvn clean -Dmaven.clean.failOnError=false # temporarily disable exiting on error set +e mvn clean -mvn install -DskipTests; -mvn package -Passembly -DskipTests +mvn install -DskipTests -Djapicmp.skip +mvn package -Passembly -DskipTests -Djapicmp.skip set -e -mvn package -Passembly -DskipTests +mvn package -Passembly -DskipTests -Djapicmp.skip git checkout main RELEASE_NOTES_BRANCH="${MVN_VERSION_RELEASE}-release-notes" diff --git a/scripts/release.sh b/scripts/release.sh index c7155b8e4df..2db8679eb21 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -139,12 +139,12 @@ git checkout main; cd scripts rm -rf temp mkdir temp -echo "MVN_CURRENT_SNAPSHOT_VERSION=\"${MVN_CURRENT_SNAPSHOT_VERSION}\"" > temp/constants.txt -echo "MVN_VERSION_RELEASE=\"${MVN_VERSION_RELEASE}\"" > temp/constants.txt -echo "MVN_NEXT_SNAPSHOT_VERSION=\"${MVN_NEXT_SNAPSHOT_VERSION}\"" > temp/constants.txt -echo "BRANCH=\"${BRANCH}\"" > temp/constants.txt -echo "RELEASE_NOTES_BRANCH=\"${RELEASE_NOTES_BRANCH}\"" > temp/constants.txt -echo "MVN_VERSION_DEVELOP=\"${MVN_VERSION_DEVELOP}\"" > temp/constants.txt +echo "MVN_CURRENT_SNAPSHOT_VERSION=\"${MVN_CURRENT_SNAPSHOT_VERSION}\"" >> temp/constants.txt +echo "MVN_VERSION_RELEASE=\"${MVN_VERSION_RELEASE}\"" >> temp/constants.txt +echo "MVN_NEXT_SNAPSHOT_VERSION=\"${MVN_NEXT_SNAPSHOT_VERSION}\"" >> temp/constants.txt +echo "BRANCH=\"${BRANCH}\"" >> temp/constants.txt +echo "RELEASE_NOTES_BRANCH=\"${RELEASE_NOTES_BRANCH}\"" >> temp/constants.txt +echo "MVN_VERSION_DEVELOP=\"${MVN_VERSION_DEVELOP}\"" >> temp/constants.txt cd .. echo "Running maven clean and install -DskipTests"; @@ -167,7 +167,6 @@ mvn versions:set -DnewVersion="${MVN_VERSION_RELEASE}" mvn versions:commit - # delete old release branch if it exits if git show-ref --verify --quiet "refs/heads/${BRANCH}"; then git branch --delete --force "${BRANCH}" &>/dev/null @@ -180,20 +179,11 @@ git tag "${MVN_VERSION_RELEASE}" echo ""; echo "Pushing release branch to github" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; # push release branch and tag git push -u origin "${BRANCH}" git push origin "${MVN_VERSION_RELEASE}" -echo ""; -echo "You need to tell Jenkins to start the release deployment processes, for SDK and maven artifacts" -echo "- SDK deployment: https://ci.eclipse.org/rdf4j/job/rdf4j-deploy-release-sdk/ " -echo "- Maven deployment: https://ci.eclipse.org/rdf4j/job/rdf4j-deploy-release-ossrh/ " -echo "(if you are on linux or windows, remember to use CTRL+SHIFT+C to copy)." -echo "Log in, then choose 'Build with Parameters' and type in ${MVN_VERSION_RELEASE}" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; - # Cleanup mvn clean -Dmaven.clean.failOnError=false mvn clean -Dmaven.clean.failOnError=false @@ -219,15 +209,13 @@ git push echo ""; echo "About to create PR" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; echo ""; echo "Creating pull request to merge release branch back into main" -gh pr create --title "next development iteration: ${MVN_NEXT_SNAPSHOT_VERSION}" --body "Merge using merge commit rather than rebase" +gh pr create -B main --title "next development iteration: ${MVN_NEXT_SNAPSHOT_VERSION}" --body "Merge using merge commit rather than rebase" echo ""; echo "Preparing a merge-branch to merge into develop" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; @@ -241,7 +229,7 @@ git push --set-upstream origin "merge_main_into_develop_after_release_${MVN_VERS echo "Creating pull request to merge the merge-branch into develop" gh pr create -B develop --title "sync develop branch after release ${MVN_VERSION_RELEASE}" --body "Merge using merge commit rather than rebase" -echo "It's ok to merge this PR later, so wait for the Jenkins tests to finish." +echo "It's ok to merge this PR later, so wait for the CI tests to finish." read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; mvn clean -Dmaven.clean.failOnError=false @@ -255,18 +243,17 @@ mvn clean -Dmaven.clean.failOnError=false mvn clean -Dmaven.clean.failOnError=false echo "Build javadocs" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; git checkout "${MVN_VERSION_RELEASE}" # temporarily disable exiting on error set +e mvn clean -mvn install -DskipTests -mvn package -Passembly -DskipTests +mvn install -DskipTests -Djapicmp.skip +mvn package -Passembly -DskipTests -Djapicmp.skip set -e -mvn package -Passembly -DskipTests +mvn package -Passembly -DskipTests -Djapicmp.skip git checkout main @@ -277,7 +264,19 @@ cp -f "site/static/javadoc/${MVN_VERSION_RELEASE}.tgz" "site/static/javadoc/late git add --all git commit -s -a -m "javadocs for ${MVN_VERSION_RELEASE}" git push --set-upstream origin "${RELEASE_NOTES_BRANCH}" -gh pr create -B main --title "${RELEASE_NOTES_BRANCH}" --body "Javadocs, release-notes and news item for ${MVN_VERSION_RELEASE}" +BODY_CONTENT=$(cat <}} diff --git a/site/content/download.md b/site/content/download.md index f6d81bad5fe..be001e0e57b 100644 --- a/site/content/download.md +++ b/site/content/download.md @@ -5,15 +5,15 @@ toc: true You can either retrieve RDF4J via Apache Maven, or download the SDK or onejar directly. -## RDF4J 4.3.12 (latest) +## RDF4J 5.0.3 (latest) -RDF4J 4.3.12 is our latest stable release. It requires Java 11 minimally. -For details on what’s new and how to upgrade, see the [release and upgrade notes](/release-notes/4.3.12). +RDF4J 5.0.3 is our latest stable release. It requires Java 11 minimally. +For details on what’s new and how to upgrade, see the [release and upgrade notes](/release-notes/5.0.3). -- [RDF4J 4.3.12 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.3.12-sdk.zip)
+- [RDF4J 5.0.3 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.3-sdk.zip)
Full Eclipse RDF4J SDK, containing all libraries, RDF4J Server, Workbench, and Console applications, and Javadoc API. -- [RDF4J 4.3.12 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.3.12-onejar.jar)
+- [RDF4J 5.0.3 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.3-onejar.jar)
Single jar file for easy inclusion of the full RDF4J toolkit in your Java project. - [RDF4J artifacts](https://search.maven.org/search?q=org.eclipse.rdf4j) on the [Maven Central Repository](http://search.maven.org/) @@ -28,7 +28,7 @@ You can include RDF4J as a Maven dependency in your Java project by including th org.eclipse.rdf4j rdf4j-bom - 4.3.12 + 5.0.3 pom import @@ -50,31 +50,21 @@ See the [Setup instructions](/documentation/programming/setup) in the [Programmer’s documentation](/documentation/) for more details on Maven and which artifacts RDF4J provides. +## Older releases -## RDF4J 5.0.0-M3 - -RDF4J 5.0.0-M3 is our latest milestone build of the upcoming 5.0.0 release. It requires Java 11 minimally. -For details on what’s new and how to upgrade, see the [release and upgrade notes](/news/rdf4j-500-M2.md). - -- [RDF4J 5.0.0-M3 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.0-M3-sdk.zip)
- Full Eclipse RDF4J SDK, containing all libraries, RDF4J Server, Workbench, and Console applications, and Javadoc API. - -- [RDF4J 5.0.0-M3 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.0-M3-onejar.jar)
- Single jar file for easy inclusion of the full RDF4J toolkit in your Java project. - -- [RDF4J artifacts](https://search.maven.org/search?q=org.eclipse.rdf4j) on the [Maven Central Repository](http://search.maven.org/) +### RDF4J 4.3 -RDF4J 5.0.0-M3 is also available through maven. +- [RDF4J 4.3.15 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.3.15-sdk.zip) +- [RDF4J 4.3.15 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.3.15-onejar.jar) -## Older releases - ### RDF4J 4.2 - [RDF4J 4.2.4 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.2.4-sdk.zip) - [RDF4J 4.2.4 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.2.4-onejar.jar) + ### RDF4J 4.1 - [RDF4J 4.1.3 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.1.3-sdk.zip) diff --git a/site/content/news/rdf4j-4313.md b/site/content/news/rdf4j-4313.md new file mode 100644 index 00000000000..ab26ae1eda7 --- /dev/null +++ b/site/content/news/rdf4j-4313.md @@ -0,0 +1,14 @@ +--- +title: "RDF4J 4.3.13 released" +date: 2024-07-24T10:33:31+0200 +layout: "single" +categories: ["news"] +--- +RDF4J 4.3.13 is now available. This is a patch release with backported fixes and improvements from 5.0.0 and 5.0.1. + +For more details, have a look at the [release notes](/release-notes/4.3.13). + +### Links + +- [Download RDF4J](/download/#rdf4j-43) +- [release notes](/release-notes/4.3.13). diff --git a/site/content/news/rdf4j-4314.md b/site/content/news/rdf4j-4314.md new file mode 100644 index 00000000000..bacfb39eef0 --- /dev/null +++ b/site/content/news/rdf4j-4314.md @@ -0,0 +1,14 @@ +--- +title: "RDF4J 4.3.14 released" +date: 2024-10-02T12:19:30+0200 +layout: "single" +categories: ["news"] +--- +RDF4J 4.3.14 is now available. This is a patch release fixing 1 bug. + +For more details, have a look at the [release notes](/release-notes/4.3.14). + +### Links + +- [Download RDF4J](/download/) +- [release notes](/release-notes/4.3.14). diff --git a/site/content/news/rdf4j-4315.md b/site/content/news/rdf4j-4315.md new file mode 100644 index 00000000000..faf97beecf3 --- /dev/null +++ b/site/content/news/rdf4j-4315.md @@ -0,0 +1,14 @@ +--- +title: "RDF4J 4.3.15 released" +date: 2024-11-07T15:39:52+0100 +layout: "single" +categories: ["news"] +--- +RDF4J 4.3.15 is now available. This is a patch release fixing 4 bugs. + +For more details, have a look at the [release notes](/release-notes/4.3.15). + +### Links + +- [Download RDF4J](/download/) +- [release notes](/release-notes/4.3.15). diff --git a/site/content/news/rdf4j-500.md b/site/content/news/rdf4j-500.md new file mode 100644 index 00000000000..9311e6ee9f0 --- /dev/null +++ b/site/content/news/rdf4j-500.md @@ -0,0 +1,25 @@ +--- +title: "RDF4J 5.0.0 released" +date: 2024-06-21T10:01:02+0200 +layout: "single" +categories: ["news"] +--- +balloons +We are very excited to announce the release of RDF4J 5.0.0! + +RDF4J 5.0.0 is a major release of the RDF4J framework with many new features and improvements. + +Highlights include: +- JSON-LD 1.1 support +- Many improvements to FedX +- Improved SHACL validation with support for [sh:closed](https://www.w3.org/TR/shacl/#ClosedConstraintComponent) and [pairwise](https://www.w3.org/TR/shacl/#core-components-property-pairs) validation +- Stability and performance improvements to the LmdbStore +- Upgrade of MapDB + - More queries with intermediary results are no longer limited by RAM/java heap but disk space available + +For more details, including instruction on how to upgrade, see the [release notes](/release-notes/5.0.0). + +### Links + +- [Download RDF4J](/download/) +- [release notes](/release-notes/5.0.0) diff --git a/site/content/news/rdf4j-501.md b/site/content/news/rdf4j-501.md new file mode 100644 index 00000000000..f538b48309b --- /dev/null +++ b/site/content/news/rdf4j-501.md @@ -0,0 +1,14 @@ +--- +title: "RDF4J 5.0.1 released" +date: 2024-07-09T17:08:30+0200 +layout: "single" +categories: ["news"] +--- +RDF4J 5.0.1 is now available. This is a patch release fixing 8 bugs. + +For more details, have a look at the [release notes](/release-notes/5.0.1). + +### Links + +- [Download RDF4J](/download/) +- [release notes](/release-notes/5.0.1). diff --git a/site/content/news/rdf4j-502.md b/site/content/news/rdf4j-502.md new file mode 100644 index 00000000000..ec2226cc8ec --- /dev/null +++ b/site/content/news/rdf4j-502.md @@ -0,0 +1,14 @@ +--- +title: "RDF4J 5.0.2 released" +date: 2024-08-02T19:33:05+0200 +layout: "single" +categories: ["news"] +--- +RDF4J 5.0.2 is now available. This is a patch release fixing 1 bugs. + +For more details, have a look at the [release notes](/release-notes/5.0.2). + +### Links + +- [Download RDF4J](/download/) +- [release notes](/release-notes/5.0.2). diff --git a/site/content/news/rdf4j-503.md b/site/content/news/rdf4j-503.md new file mode 100644 index 00000000000..0f3a7675648 --- /dev/null +++ b/site/content/news/rdf4j-503.md @@ -0,0 +1,14 @@ +--- +title: "RDF4J 5.0.3 released" +date: 2024-11-10T14:15:45+0100 +layout: "single" +categories: ["news"] +--- +RDF4J 5.0.3 is now available. This is a patch release fixing 11 bugs. + +For more details, have a look at the [release notes](/release-notes/5.0.3). + +### Links + +- [Download RDF4J](/download/) +- [release notes](/release-notes/5.0.3). diff --git a/site/content/news/rdf4j-510-M1.md b/site/content/news/rdf4j-510-M1.md new file mode 100644 index 00000000000..03d90cf2bb0 --- /dev/null +++ b/site/content/news/rdf4j-510-M1.md @@ -0,0 +1,20 @@ +--- +title: "RDF4J 5.1.0 Milestone 1" +date: 2024-11-10T14:05:43+0100 +layout: "single" +categories: ["news"] +--- +Milestone number 1 of the upcoming 5.1.0 release of RDF4J is now available for download. + +RDF4J 5.1.0 is a minor release focusing on ... . + +This milestone build is not yet feature-complete, but we are putting it out to receive early feedback on all the improvements we have put in. + + + + - [issues fixed in 5.1.0 Milestone 1](https://github.com/eclipse/rdf4j/issues?q=is%3Aissue+label%3AM1+is%3Aclosed+milestone%3A5.1.0) + - [issues planned for 5.1.0](https://github.com/eclipse/rdf4j/milestone/107) + +### Links + +- [Download RDF4J](/download/) diff --git a/site/content/release-notes/4.3.13.md b/site/content/release-notes/4.3.13.md new file mode 100644 index 00000000000..728b5aff2ba --- /dev/null +++ b/site/content/release-notes/4.3.13.md @@ -0,0 +1,13 @@ +--- +title: "4.3.13" +toc: true +--- +RDF4J 4.3.13 is a patch release with backported fixes and improvements from 5.0.0 and 5.0.1. + +For a complete overview, see [all issues fixed in 4.3.13](https://github.com/eclipse/rdf4j/milestone/106?closed=1). + +Some dependencies have been bumped to mitigate security vulnerabilities. See: https://github.com/eclipse-rdf4j/rdf4j/issues/5088 + +### Acknowledgements + +This release was made possible by contributions from Bart Hanssens, Håvard M. Ottestad and Florian Kleedorfer. diff --git a/site/content/release-notes/4.3.14.md b/site/content/release-notes/4.3.14.md new file mode 100644 index 00000000000..f0b60686d06 --- /dev/null +++ b/site/content/release-notes/4.3.14.md @@ -0,0 +1,8 @@ +--- +title: "4.3.14" +toc: true +--- +RDF4J 4.3.14 is a patch release that fixes 1 issue. + +For a complete overview, see [all issues fixed in 4.3.14](https://github.com/eclipse/rdf4j/milestone/110?closed=1). + diff --git a/site/content/release-notes/4.3.15.md b/site/content/release-notes/4.3.15.md new file mode 100644 index 00000000000..8a454c89203 --- /dev/null +++ b/site/content/release-notes/4.3.15.md @@ -0,0 +1,7 @@ +--- +title: "4.3.15" +toc: true +--- +RDF4J 4.3.15 is a patch release that fixes 4 issues. + +For a complete overview, see [all issues fixed in 4.3.15](https://github.com/eclipse/rdf4j/milestone/112?closed=1). diff --git a/site/content/release-notes/5.0.0.md b/site/content/release-notes/5.0.0.md index 199d8dc735a..d495494f5ed 100644 --- a/site/content/release-notes/5.0.0.md +++ b/site/content/release-notes/5.0.0.md @@ -5,15 +5,21 @@ toc: true RDF4J 5.0.0 is a major release of the Eclipse RDF4J framework. Some highlights: - Replacement of the custom Iteration interface with Java Iterable/Iterator -- Upgrade of MapDB - Replacement of old openrdf.org config vocabulary IRIS with new rdf4j.org vocabulary +- Improved SHACL validation with support for [sh:closed](https://www.w3.org/TR/shacl/#ClosedConstraintComponent) and [pairwise](https://www.w3.org/TR/shacl/#core-components-property-pairs) validation +- Upgrade of MapDB + - More queries with intermediary results are no longer limited by RAM/java heap but disk space available +- Improve performance, query throughput and correctness in a transparent federation by refining various evaluation strategies (bind joins, property paths, limit pushing, ...) +- JSON-LD 1.1 support +- Implementation of merge join for future use in query evaluation +- Stability and performance improvements to the LmdbStore +- Improved spilling to disk for large transactions For a complete overview, see [all issues fixed in 5.0.0](https://github.com/eclipse/rdf4j/milestone/80?closed=1). ## Upgrade notes -RDF4J 5.0.0 contains several [backward incompatible -changes](https://github.com/eclipse/rdf4j/issues?q=is%3Aclosed+is%3Aissue+label%3A%22%E2%9B%94+Not+backwards+compatible%22+milestone%3A%225.0.0%22), including removal of several deprecated modules and classes. +RDF4J 5.0.0 contains several [backward incompatible changes](https://github.com/eclipse/rdf4j/issues?q=is%3Aclosed+is%3Aissue+label%3A%22%E2%9B%94+Not+backwards+compatible%22+milestone%3A%225.0.0%22), including removal of several deprecated modules and classes. ### Configuration vocabulary upgrade diff --git a/site/content/release-notes/5.0.1.md b/site/content/release-notes/5.0.1.md new file mode 100644 index 00000000000..2ff797a6c47 --- /dev/null +++ b/site/content/release-notes/5.0.1.md @@ -0,0 +1,24 @@ +--- +title: "5.0.1" +toc: true +--- +RDF4J 5.0.1 is a patch release that fixes 8 issues. + +For a complete overview, see [all issues fixed in 5.0.1](https://github.com/eclipse/rdf4j/milestone/108?closed=1). + +### Security + +The following dependencies and/or transitive dependencies have been updated to address security vulnerabilities: + - Upgraded spring to 5.3.37 + - Upgraded snappy-java to 1.1.10.5 + - Upgraded netty to 4.1.111 + +These upgrades fix several issues reported in various CVEs (more details can be found in the RDF4J github [issue list](https://github.com/eclipse-rdf4j/rdf4j/issues?q=is%3Aissue+label%3Asecurity+is%3Aclosed) ). +While these vulnerabilities may or may not affect the security of RDF4J itself in a real-world environment, +users are nevertheless recommended to consider upgrading to the latest version of RDF4J. + + +### Acknowledgements + +This release was made possible by contributions from Florian Kleedorfer, Håvard M. Ottestad, Matthew Nguyen, Bart Hanssens, +Pete Edwards and Jerven Bolleman. diff --git a/site/content/release-notes/5.0.2.md b/site/content/release-notes/5.0.2.md new file mode 100644 index 00000000000..94fe2fffaa4 --- /dev/null +++ b/site/content/release-notes/5.0.2.md @@ -0,0 +1,7 @@ +--- +title: "5.0.2" +toc: true +--- +RDF4J 5.0.2 is a patch release that fixes 1 issue. + +For a complete overview, see [all issues fixed in 5.0.2](https://github.com/eclipse/rdf4j/milestone/109?closed=1). diff --git a/site/content/release-notes/5.0.3.md b/site/content/release-notes/5.0.3.md new file mode 100644 index 00000000000..3f294c15f41 --- /dev/null +++ b/site/content/release-notes/5.0.3.md @@ -0,0 +1,11 @@ +--- +title: "5.0.3" +toc: true +--- +RDF4J 5.0.3 is a patch release that fixes 11 issues. + +For a complete overview, see [all issues fixed in 5.0.3](https://github.com/eclipse/rdf4j/milestone/111?closed=1). + +### Acknowledgements + +This release was made possible by contributions from Hannes Ebner, Håvard M. Ottestad, Frens Jan Rumph and Andreas Schwarte. diff --git a/site/static/javadoc/4.3.13.tgz b/site/static/javadoc/4.3.13.tgz new file mode 100644 index 00000000000..b950e3580eb Binary files /dev/null and b/site/static/javadoc/4.3.13.tgz differ diff --git a/site/static/javadoc/4.3.14.tgz b/site/static/javadoc/4.3.14.tgz new file mode 100644 index 00000000000..8ae2d5a6f86 Binary files /dev/null and b/site/static/javadoc/4.3.14.tgz differ diff --git a/site/static/javadoc/4.3.15.tgz b/site/static/javadoc/4.3.15.tgz new file mode 100644 index 00000000000..49f8832f60f Binary files /dev/null and b/site/static/javadoc/4.3.15.tgz differ diff --git a/site/static/javadoc/5.0.0.tgz b/site/static/javadoc/5.0.0.tgz new file mode 100644 index 00000000000..5374065d234 Binary files /dev/null and b/site/static/javadoc/5.0.0.tgz differ diff --git a/site/static/javadoc/5.0.1.tgz b/site/static/javadoc/5.0.1.tgz new file mode 100644 index 00000000000..8089a1aa8c3 Binary files /dev/null and b/site/static/javadoc/5.0.1.tgz differ diff --git a/site/static/javadoc/5.0.2.tgz b/site/static/javadoc/5.0.2.tgz new file mode 100644 index 00000000000..c1bb73c54e3 Binary files /dev/null and b/site/static/javadoc/5.0.2.tgz differ diff --git a/site/static/javadoc/5.0.3.tgz b/site/static/javadoc/5.0.3.tgz new file mode 100644 index 00000000000..28d3c04edfa Binary files /dev/null and b/site/static/javadoc/5.0.3.tgz differ diff --git a/site/static/javadoc/5.1.0-M1.tgz b/site/static/javadoc/5.1.0-M1.tgz new file mode 100644 index 00000000000..2f280877c5c Binary files /dev/null and b/site/static/javadoc/5.1.0-M1.tgz differ diff --git a/site/static/javadoc/latest.tgz b/site/static/javadoc/latest.tgz index 657de822519..28d3c04edfa 100644 Binary files a/site/static/javadoc/latest.tgz and b/site/static/javadoc/latest.tgz differ diff --git a/spring-components/pom.xml b/spring-components/pom.xml index 2d4a4778b2e..9ff3131249a 100644 --- a/spring-components/pom.xml +++ b/spring-components/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT pom diff --git a/spring-components/rdf4j-spring-demo/pom.xml b/spring-components/rdf4j-spring-demo/pom.xml index 415e4b98d50..c1311b7fe2a 100644 --- a/spring-components/rdf4j-spring-demo/pom.xml +++ b/spring-components/rdf4j-spring-demo/pom.xml @@ -7,7 +7,7 @@ org.eclipse.rdf4j rdf4j-spring-components - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT diff --git a/spring-components/rdf4j-spring/pom.xml b/spring-components/rdf4j-spring/pom.xml index a25834e11c6..8a16a1ea55e 100644 --- a/spring-components/rdf4j-spring/pom.xml +++ b/spring-components/rdf4j-spring/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-spring-components - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-spring RDF4J: Spring diff --git a/spring-components/rdf4j-spring/src/main/java/org/eclipse/rdf4j/spring/support/RDF4JTemplate.java b/spring-components/rdf4j-spring/src/main/java/org/eclipse/rdf4j/spring/support/RDF4JTemplate.java index 0dbac366732..86cf1d27143 100644 --- a/spring-components/rdf4j-spring/src/main/java/org/eclipse/rdf4j/spring/support/RDF4JTemplate.java +++ b/spring-components/rdf4j-spring/src/main/java/org/eclipse/rdf4j/spring/support/RDF4JTemplate.java @@ -315,7 +315,9 @@ public void delete(IRI start, List propertyPaths) { Variable p2 = SparqlBuilder.var("p2_" + i); Variable s2 = SparqlBuilder.var("s2_" + i); q.delete(target.has(p1, o1), s2.has(p2, target)) - .where(toIri(start).has(p, target).optional(), target.has(p1, o1).optional(), + .where( + toIri(start).has(p, target), + target.has(p1, o1).optional(), s2.has(p2, target).optional()); } update(q.getQueryString()).execute(); diff --git a/spring-components/rdf4j-spring/src/test/java/org/eclipse/rdf4j/spring/domain/model/EX.java b/spring-components/rdf4j-spring/src/test/java/org/eclipse/rdf4j/spring/domain/model/EX.java index d68ef9b6d9d..361b38061e7 100644 --- a/spring-components/rdf4j-spring/src/test/java/org/eclipse/rdf4j/spring/domain/model/EX.java +++ b/spring-components/rdf4j-spring/src/test/java/org/eclipse/rdf4j/spring/domain/model/EX.java @@ -34,6 +34,7 @@ public class EX { public static final IRI sunflowers = SimpleValueFactory.getInstance().createIRI(base, "sunflowers"); public static final IRI potatoEaters = SimpleValueFactory.getInstance().createIRI(base, "potatoEaters"); public static final IRI guernica = SimpleValueFactory.getInstance().createIRI(base, "guernica"); + public static final IRI homeAddress = SimpleValueFactory.getInstance().createIRI(base, "homeAddress"); public static IRI of(String localName) { return SimpleValueFactory.getInstance().createIRI(base, localName); diff --git a/spring-components/rdf4j-spring/src/test/java/org/eclipse/rdf4j/spring/support/RDF4JTemplateTests.java b/spring-components/rdf4j-spring/src/test/java/org/eclipse/rdf4j/spring/support/RDF4JTemplateTests.java index 99270244368..514b96b8804 100644 --- a/spring-components/rdf4j-spring/src/test/java/org/eclipse/rdf4j/spring/support/RDF4JTemplateTests.java +++ b/spring-components/rdf4j-spring/src/test/java/org/eclipse/rdf4j/spring/support/RDF4JTemplateTests.java @@ -7,10 +7,14 @@ * http://www.eclipse.org/org/documents/edl-v10.php. * * SPDX-License-Identifier: BSD-3-Clause - *******************************************************************************/ + ******************************************************************************/ package org.eclipse.rdf4j.spring.support; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + import java.util.List; import java.util.Set; @@ -20,13 +24,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.query.BindingSet; import org.eclipse.rdf4j.sparqlbuilder.constraint.propertypath.builder.PropertyPathBuilder; import org.eclipse.rdf4j.sparqlbuilder.rdf.Rdf; import org.eclipse.rdf4j.spring.RDF4JSpringTestBase; +import org.eclipse.rdf4j.spring.dao.exception.IncorrectResultSetSizeException; import org.eclipse.rdf4j.spring.dao.support.opbuilder.UpdateExecutionBuilder; import org.eclipse.rdf4j.spring.dao.support.sparql.NamedSparqlSupplier; +import org.eclipse.rdf4j.spring.domain.dao.ArtistDao; +import org.eclipse.rdf4j.spring.domain.dao.PaintingDao; +import org.eclipse.rdf4j.spring.domain.model.Artist; import org.eclipse.rdf4j.spring.domain.model.EX; +import org.eclipse.rdf4j.spring.domain.model.Painting; import org.eclipse.rdf4j.spring.util.QueryResultUtils; +import org.eclipse.rdf4j.spring.util.TypeMappingUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -40,6 +51,13 @@ public class RDF4JTemplateTests extends RDF4JSpringTestBase { @Autowired private RDF4JTemplate rdf4JTemplate; + // used for checks + @Autowired + private ArtistDao artistDao; + + @Autowired + PaintingDao paintingDao; + @Test public void testUpdate1() { UpdateExecutionBuilder updateBuilder = rdf4JTemplate.update( @@ -427,6 +445,62 @@ public void testAssociate_deleteOutgoing() { } + @Test + public void testDeleteWithPropertyPaths() { + int triplesBeforeDelete = countTriples(); + Artist picasso = artistDao.getById(EX.Picasso); + assertNotNull(picasso); + Painting guernica = paintingDao.getById(EX.guernica); + assertNotNull(guernica); + rdf4JTemplate.delete(EX.Picasso, List.of(PropertyPathBuilder.of(EX.creatorOf).build())); + assertThrows(IncorrectResultSetSizeException.class, () -> artistDao.getById(EX.Picasso)); + assertThrows(IncorrectResultSetSizeException.class, () -> paintingDao.getById(EX.guernica)); + assertEquals(triplesBeforeDelete - 8, countTriples()); + } + + @Test + public void testDeleteWithDisjunctivePropertyPaths() { + int triplesBeforeDelete = countTriples(); + Artist picasso = artistDao.getById(EX.Picasso); + assertNotNull(picasso); + Painting guernica = paintingDao.getById(EX.guernica); + assertNotNull(guernica); + rdf4JTemplate.delete(EX.Picasso, List.of(PropertyPathBuilder.of(EX.creatorOf).or(EX.homeAddress).build())); + assertThrows(IncorrectResultSetSizeException.class, () -> artistDao.getById(EX.Picasso)); + assertThrows(IncorrectResultSetSizeException.class, () -> paintingDao.getById(EX.guernica)); + assertEquals(triplesBeforeDelete - 11, countTriples()); + } + + @Test + public void testDeleteWithMultiplePropertyPaths() { + int triplesBeforeDelete = countTriples(); + Artist picasso = artistDao.getById(EX.Picasso); + assertNotNull(picasso); + Painting guernica = paintingDao.getById(EX.guernica); + assertNotNull(guernica); + rdf4JTemplate.delete(EX.Picasso, + List.of(PropertyPathBuilder.of(EX.creatorOf).build(), PropertyPathBuilder.of(EX.homeAddress).build())); + assertThrows(IncorrectResultSetSizeException.class, () -> artistDao.getById(EX.Picasso)); + assertThrows(IncorrectResultSetSizeException.class, () -> paintingDao.getById(EX.guernica)); + assertEquals(triplesBeforeDelete - 11, countTriples()); + } + + @Test + public void testDeleteWithLongerPropertyPaths() { + int triplesBeforeDelete = countTriples(); + Artist picasso = artistDao.getById(EX.Picasso); + assertNotNull(picasso); + Painting guernica = paintingDao.getById(EX.guernica); + assertNotNull(guernica); + // deletes guernica and the home address, but not picasso + rdf4JTemplate.delete(EX.guernica, + List.of(PropertyPathBuilder.of(EX.creatorOf).inv().then(EX.homeAddress).build())); + picasso = artistDao.getById(EX.Picasso); + assertNotNull(picasso); + assertThrows(IncorrectResultSetSizeException.class, () -> paintingDao.getById(EX.guernica)); + assertEquals(triplesBeforeDelete - 8, countTriples()); + } + @Test public void testAssociate() { IRI me = EX.of("me"); @@ -464,4 +538,14 @@ public void testAssociate() { .size()); } + + private int countTriples() { + return this.rdf4JTemplate + .tupleQuery("SELECT (count(*) AS ?count) WHERE { ?a ?b ?c }") + .evaluateAndConvert() + .toSingletonOfWholeResult(result -> { + BindingSet bs = result.next(); + return TypeMappingUtils.toInt(QueryResultUtils.getValue(bs, "count")); + }); + } } diff --git a/spring-components/spring-boot-sparql-web/pom.xml b/spring-components/spring-boot-sparql-web/pom.xml index 16c412fce30..4d86156755a 100644 --- a/spring-components/spring-boot-sparql-web/pom.xml +++ b/spring-components/spring-boot-sparql-web/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-spring-components - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-spring-boot-sparql-web RDF4J: Spring boot component for a HTTP sparql server diff --git a/testsuites/benchmark/pom.xml b/testsuites/benchmark/pom.xml index 2d34015255f..4bf66ee78da 100644 --- a/testsuites/benchmark/pom.xml +++ b/testsuites/benchmark/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-benchmark RDF4J: benchmarks diff --git a/testsuites/geosparql/pom.xml b/testsuites/geosparql/pom.xml index 407b995d69d..71282dc24b1 100644 --- a/testsuites/geosparql/pom.xml +++ b/testsuites/geosparql/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-geosparql-testsuite RDF4J: GeoSPARQL compliance test suite diff --git a/testsuites/lucene/pom.xml b/testsuites/lucene/pom.xml index 361316e5bf6..5d78d900116 100644 --- a/testsuites/lucene/pom.xml +++ b/testsuites/lucene/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-lucene-testsuite RDF4J: Lucene Sail Tests diff --git a/testsuites/model/pom.xml b/testsuites/model/pom.xml index dc30dec13c8..f5de1f6f4c6 100644 --- a/testsuites/model/pom.xml +++ b/testsuites/model/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-model-testsuite RDF4J: Model API testsuite diff --git a/testsuites/pom.xml b/testsuites/pom.xml index ef6292c21da..677238976b9 100644 --- a/testsuites/pom.xml +++ b/testsuites/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-testsuites pom diff --git a/testsuites/queryresultio/pom.xml b/testsuites/queryresultio/pom.xml index ecd8e5bc82d..5051bdbadad 100644 --- a/testsuites/queryresultio/pom.xml +++ b/testsuites/queryresultio/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-queryresultio-testsuite RDF4J: QueryResultIO testsuite diff --git a/testsuites/repository/pom.xml b/testsuites/repository/pom.xml index 4bbb5674036..e3617f8904b 100644 --- a/testsuites/repository/pom.xml +++ b/testsuites/repository/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-repository-testsuite RDF4J: Repository API testsuite diff --git a/testsuites/rio/pom.xml b/testsuites/rio/pom.xml index d0496fde84c..223c1ae1fc7 100644 --- a/testsuites/rio/pom.xml +++ b/testsuites/rio/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-rio-testsuite RDF4J: Rio compliance test suite diff --git a/testsuites/sail/pom.xml b/testsuites/sail/pom.xml index c4cab60ac29..ec7afe5d121 100644 --- a/testsuites/sail/pom.xml +++ b/testsuites/sail/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-sail-testsuite RDF4J: Sail API testsuite diff --git a/testsuites/sail/src/main/java/org/eclipse/rdf4j/testsuite/sail/SailConcurrencyTest.java b/testsuites/sail/src/main/java/org/eclipse/rdf4j/testsuite/sail/SailConcurrencyTest.java index 0823aab17e3..4ee406b0e7f 100644 --- a/testsuites/sail/src/main/java/org/eclipse/rdf4j/testsuite/sail/SailConcurrencyTest.java +++ b/testsuites/sail/src/main/java/org/eclipse/rdf4j/testsuite/sail/SailConcurrencyTest.java @@ -37,6 +37,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -155,6 +156,7 @@ public int getSize() { * @see https://github.com/eclipse/rdf4j/issues/693 */ @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testConcurrentAddLargeTxn() throws Exception { logger.info("executing two large concurrent transactions"); final CountDownLatch runnersDone = new CountDownLatch(2); @@ -196,6 +198,7 @@ public void testConcurrentAddLargeTxn() throws Exception { * one of the transactions rolls back at the end. */ @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testConcurrentAddLargeTxnRollback() throws Exception { logger.info("executing two large concurrent transactions"); final CountDownLatch runnersDone = new CountDownLatch(2); @@ -237,6 +240,7 @@ public void testConcurrentAddLargeTxnRollback() throws Exception { } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) @Disabled("This test takes a long time and accomplishes little extra") public void testGetContextIDs() throws Exception { // Create one thread which writes statements to the repository, on a @@ -314,6 +318,7 @@ public void testGetContextIDs() throws Exception { } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testConcurrentConnectionsShutdown() throws InterruptedException { if (store instanceof AbstractSail) { ((AbstractSail) store).setConnectionTimeOut(200); @@ -356,7 +361,90 @@ public void testConcurrentConnectionsShutdown() throws InterruptedException { } + // @Disabled @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) + public void testSerialThreads() throws InterruptedException { + if (store instanceof AbstractSail) { + ((AbstractSail) store).setConnectionTimeOut(200); + } else if (store instanceof SailWrapper) { + Sail baseSail = ((SailWrapper) store).getBaseSail(); + if (baseSail instanceof AbstractSail) { + ((AbstractSail) baseSail).setConnectionTimeOut(200); + } + } + + try (SailConnection connection = store.getConnection()) { + connection.begin(); + connection.addStatement(RDF.TYPE, RDF.TYPE, RDF.PROPERTY, RDF.TYPE); + connection.commit(); + } + + AtomicReference connection1 = new AtomicReference<>(); + + Thread thread1 = new Thread(() -> { + SailConnection connection = store.getConnection(); + connection1.setRelease(connection); + + }); + + thread1.start(); + thread1.join(); + + thread1 = new Thread(() -> { + SailConnection connection = connection1.getAcquire(); + connection.begin(IsolationLevels.NONE); + }); + + thread1.start(); + thread1.join(); + + thread1 = new Thread(() -> { + SailConnection connection = connection1.getAcquire(); + connection.addStatement(RDF.FIRST, RDF.TYPE, RDF.PROPERTY); + }); + + thread1.start(); + thread1.join(); + + thread1 = new Thread(() -> { + SailConnection connection = connection1.getAcquire(); + connection.clear(RDF.TYPE); + }); + + thread1.start(); + thread1.join(); + + thread1 = new Thread(() -> { + SailConnection connection = connection1.getAcquire(); + connection.commit(); + }); + + thread1.start(); + thread1.join(); + + thread1 = new Thread(() -> { + SailConnection connection = connection1.getAcquire(); + connection.close(); + }); + + thread1.start(); + thread1.join(); + + try (SailConnection connection = store.getConnection()) { + connection.begin(); + long size = connection.size(); + assertEquals(1, size); + connection.clear(); + connection.commit(); + } + + store.shutDown(); + + } + + @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testConcurrentConnectionsShutdownReadCommitted() throws InterruptedException { if (store instanceof AbstractSail) { ((AbstractSail) store).setConnectionTimeOut(200); @@ -412,6 +500,7 @@ public void testConcurrentConnectionsShutdownReadCommitted() throws InterruptedE } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testConcurrentConnectionsShutdownAndClose() throws InterruptedException { if (store instanceof AbstractSail) { ((AbstractSail) store).setConnectionTimeOut(200); @@ -472,10 +561,22 @@ public void testConcurrentConnectionsShutdownAndClose() throws InterruptedExcept assertThat(size).isLessThanOrEqualTo(1); } + try (SailConnection connection = store.getConnection()) { + connection.begin(); + connection.addStatement(RDF.TYPE, RDF.TYPE, RDF.PROPERTY); + connection.commit(); + } + try (SailConnection connection = store.getConnection()) { + connection.begin(); + connection.clear(); + connection.commit(); + } + store.shutDown(); } @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) public void testConcurrentConnectionsShutdownAndCloseRollback() throws InterruptedException { if (store instanceof AbstractSail) { ((AbstractSail) store).setConnectionTimeOut(200); diff --git a/testsuites/sparql/pom.xml b/testsuites/sparql/pom.xml index a31c1387506..1a4e54e0e78 100644 --- a/testsuites/sparql/pom.xml +++ b/testsuites/sparql/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-testsuites - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-sparql-testsuite RDF4J: SPARQL compliance test suite diff --git a/tools/config/pom.xml b/tools/config/pom.xml index 0a517becf13..c3d008241cf 100644 --- a/tools/config/pom.xml +++ b/tools/config/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-tools - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-config RDF4J: application configuration diff --git a/tools/console/pom.xml b/tools/console/pom.xml index 774ac4c1871..b5f504d25f9 100644 --- a/tools/console/pom.xml +++ b/tools/console/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-tools - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-console RDF4J: Console diff --git a/tools/federation/pom.xml b/tools/federation/pom.xml index 2516c478a19..b6b1d3f9c30 100644 --- a/tools/federation/pom.xml +++ b/tools/federation/pom.xml @@ -8,7 +8,7 @@ org.eclipse.rdf4j rdf4j-tools - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT @@ -92,7 +92,7 @@ ${project.groupId} - rdf4j-collection-factory-mapdb + rdf4j-collection-factory-mapdb3 ${project.version} diff --git a/tools/federation/src/main/java/org/eclipse/rdf4j/federated/FedX.java b/tools/federation/src/main/java/org/eclipse/rdf4j/federated/FedX.java index 4d3ec554b66..568ae96d56a 100644 --- a/tools/federation/src/main/java/org/eclipse/rdf4j/federated/FedX.java +++ b/tools/federation/src/main/java/org/eclipse/rdf4j/federated/FedX.java @@ -17,7 +17,7 @@ import java.util.function.Supplier; import org.eclipse.rdf4j.collection.factory.api.CollectionFactory; -import org.eclipse.rdf4j.collection.factory.mapdb.MapDbCollectionFactory; +import org.eclipse.rdf4j.collection.factory.mapdb.MapDb3CollectionFactory; import org.eclipse.rdf4j.common.transaction.IsolationLevels; import org.eclipse.rdf4j.federated.endpoint.Endpoint; import org.eclipse.rdf4j.federated.endpoint.ResolvableEndpoint; @@ -247,6 +247,6 @@ public void setRepositoryResolver(RepositoryResolver resolver) { @Override public Supplier getCollectionFactory() { - return () -> new MapDbCollectionFactory(getIterationCacheSyncThreshold()); + return () -> new MapDb3CollectionFactory(getIterationCacheSyncThreshold()); } } diff --git a/tools/federation/src/main/java/org/eclipse/rdf4j/federated/monitoring/MonitoringImpl.java b/tools/federation/src/main/java/org/eclipse/rdf4j/federated/monitoring/MonitoringImpl.java index c53fae51671..e0e38b97823 100644 --- a/tools/federation/src/main/java/org/eclipse/rdf4j/federated/monitoring/MonitoringImpl.java +++ b/tools/federation/src/main/java/org/eclipse/rdf4j/federated/monitoring/MonitoringImpl.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.rdf4j.federated.FedXConfig; import org.eclipse.rdf4j.federated.endpoint.Endpoint; @@ -50,11 +51,7 @@ public class MonitoringImpl implements MonitoringService { @Override public void monitorRemoteRequest(Endpoint e) { - MonitoringInformation m = requestMap.get(e); - if (m == null) { - m = new MonitoringInformation(e); - requestMap.put(e, m); - } + MonitoringInformation m = requestMap.computeIfAbsent(e, (endpoint) -> new MonitoringInformation(endpoint)); m.increaseRequests(); } @@ -75,20 +72,19 @@ public void resetMonitoringInformation() { public static class MonitoringInformation { private final Endpoint e; - private int numberOfRequests = 0; + private AtomicInteger numberOfRequests = new AtomicInteger(0); public MonitoringInformation(Endpoint e) { this.e = e; } private void increaseRequests() { - // TODO make thread safe - numberOfRequests++; + numberOfRequests.incrementAndGet(); } @Override public String toString() { - return e.getName() + " => " + numberOfRequests; + return e.getName() + " => " + numberOfRequests.get(); } public Endpoint getE() { @@ -96,7 +92,7 @@ public Endpoint getE() { } public int getNumberOfRequests() { - return numberOfRequests; + return numberOfRequests.get(); } } diff --git a/tools/pom.xml b/tools/pom.xml index c1c6c02c729..92afba01321 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-tools pom diff --git a/tools/runtime-osgi/pom.xml b/tools/runtime-osgi/pom.xml index c6eb5a4ef76..2396c84c4e7 100644 --- a/tools/runtime-osgi/pom.xml +++ b/tools/runtime-osgi/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-tools - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-runtime-osgi bundle diff --git a/tools/runtime/pom.xml b/tools/runtime/pom.xml index 58ed0f6d639..ccea1ec1f55 100644 --- a/tools/runtime/pom.xml +++ b/tools/runtime/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-tools - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-runtime RDF4J: Runtime diff --git a/tools/server-spring/pom.xml b/tools/server-spring/pom.xml index 9213d3cda9e..5a967e34384 100644 --- a/tools/server-spring/pom.xml +++ b/tools/server-spring/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-tools - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-http-server-spring RDF4J: HTTP server - core diff --git a/tools/server/pom.xml b/tools/server/pom.xml index 05e9a3dee02..6818256e961 100644 --- a/tools/server/pom.xml +++ b/tools/server/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-tools - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-http-server war diff --git a/tools/workbench/pom.xml b/tools/workbench/pom.xml index 71b861d3584..82c3fa7f1e9 100644 --- a/tools/workbench/pom.xml +++ b/tools/workbench/pom.xml @@ -4,7 +4,7 @@ org.eclipse.rdf4j rdf4j-tools - 5.0.1-SNAPSHOT + 5.0.4-SNAPSHOT rdf4j-http-workbench war