Skip to content
This repository has been archived by the owner on Feb 22, 2020. It is now read-only.

Commit

Permalink
eclipse-rdf4j/rdf4j#1354 support for sh:or with sh:nodeKind
Browse files Browse the repository at this point in the history
Signed-off-by: Håvard Ottestad <[email protected]>
  • Loading branch information
hmottestad committed Mar 19, 2019
1 parent fdaa8b7 commit 232a70b
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,7 @@ public PlanNode getPlan(ShaclSailConnection shaclSailConnection, NodeShape nodeS
public SourceConstraintComponent getSourceConstraintComponent() {
return SourceConstraintComponent.NodeKindConstraintComponent;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public NodeShape(Resource id, SailRepositoryConnection connection, boolean deact
if (!deactivated) {
propertyShapes = PropertyShape.Factory.getPropertyShapes(id, connection, this);
nodeShapes = PropertyShape.Factory.getPropertyShapesInner(connection, this, id);
System.out.println();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,58 +41,65 @@ public class OrPropertyShape extends PropertyShape {
private static final Logger logger = LoggerFactory.getLogger(OrPropertyShape.class);

OrPropertyShape(Resource id, SailRepositoryConnection connection, NodeShape nodeShape, boolean deactivated,
Resource or) {
Resource or) {
super(id, nodeShape, deactivated);
this.or = toList(connection, or).stream()
.map(v -> PropertyShape.Factory.getPropertyShapesInner(connection, nodeShape, (Resource) v))
.collect(Collectors.toList());
.map(v -> PropertyShape.Factory.getPropertyShapesInner(connection, nodeShape, (Resource) v))
.collect(Collectors.toList());

}

@Override
public PlanNode getPlan(ShaclSailConnection shaclSailConnection, NodeShape nodeShape, boolean printPlans,
PlanNode overrideTargetNode) {
PlanNode overrideTargetNode) {
if (deactivated) {
return null;
}

List<List<PlanNode>> initialPlanNodes = or.stream()
.map(shapes -> shapes.stream()
.map(shape -> shape.getPlan(shaclSailConnection, nodeShape, false, null))
.filter(Objects::nonNull)
.collect(Collectors.toList()))
.filter(list -> !list.isEmpty())
.collect(Collectors.toList());
.map(shapes -> shapes.stream()
.map(shape -> shape.getPlan(shaclSailConnection, nodeShape, false, null))
.filter(Objects::nonNull)
.collect(Collectors.toList()))
.filter(list -> !list.isEmpty())
.collect(Collectors.toList());

BufferedSplitter targetNodesToValidate;
if (overrideTargetNode == null) {
targetNodesToValidate = new BufferedSplitter(unionAll(initialPlanNodes.stream()
.flatMap(Collection::stream)
.map(p -> new TrimTuple(p, 0, 1)) // we only want the targets
.collect(Collectors.toList())));
.flatMap(Collection::stream)
.map(p -> new TrimTuple(p, 0, 1)) // we only want the targets
.collect(Collectors.toList())));

} else {
targetNodesToValidate = new BufferedSplitter(overrideTargetNode);
}

List<List<PlanNode>> plannodes = or.stream().map(shapes -> shapes.stream().map(shape -> {
if (shaclSailConnection.stats.isBaseSailEmpty()) {
return shape.getPlan(shaclSailConnection, nodeShape, false, null);
}
return shape.getPlan(shaclSailConnection, nodeShape, false,
new LoggingNode(targetNodesToValidate.getPlanNode(), ""));
}).filter(Objects::nonNull).collect(Collectors.toList()))
.filter(list -> !list.isEmpty())
.collect(Collectors.toList());
List<List<PlanNode>> plannodes = or
.stream()
.map(shapes ->
shapes
.stream()
.map(shape -> {
if (shaclSailConnection.stats.isBaseSailEmpty()) {
return shape.getPlan(shaclSailConnection, nodeShape, false, null);
}
return shape.getPlan(shaclSailConnection, nodeShape, false, new LoggingNode(targetNodesToValidate.getPlanNode(), ""));
})
.filter(Objects::nonNull)
.collect(Collectors.toList())
)
.filter(list -> !list.isEmpty())
.collect(Collectors.toList());

List<IteratorData> iteratorDataTypes = plannodes.stream()
.flatMap(shapes -> shapes.stream().map(PlanNode::getIteratorDataType))
.distinct()
.collect(Collectors.toList());
.flatMap(shapes -> shapes.stream().map(PlanNode::getIteratorDataType))
.distinct()
.collect(Collectors.toList());

if (iteratorDataTypes.size() > 1) {
throw new UnsupportedOperationException(
"No support for OR shape with mix between aggregate and raw triples");
"No support for OR shape with mix between aggregate and raw triples");
}

IteratorData iteratorData = iteratorDataTypes.get(0);
Expand All @@ -103,33 +110,33 @@ public PlanNode getPlan(ShaclSailConnection shaclSailConnection, NodeShape nodeS
if (collect.size() > 1) {
iteratorData = IteratorData.aggregated;
}
if(collect.stream().anyMatch(Objects::isNull)){
iteratorData = IteratorData.aggregated;
}
}

PlanNode ret;

if (iteratorData == IteratorData.tripleBased) {

EqualsJoin equalsJoin = new EqualsJoin(unionAll(plannodes.get(0)), unionAll(plannodes.get(1)), true);
PlanNode equalsJoin = new LoggingNode(new EqualsJoin(unionAll(plannodes.get(0)), unionAll(plannodes.get(1)), true), "");

for (int i = 2; i < plannodes.size(); i++) {
equalsJoin = new EqualsJoin(equalsJoin, unionAll(plannodes.get(i)), true);
equalsJoin = new LoggingNode(new EqualsJoin(equalsJoin, unionAll(plannodes.get(i)), true), "");
}

ret = new LoggingNode(equalsJoin, "");
} else if (iteratorData == IteratorData.aggregated) {

PlanNode innerJoin = new LoggingNode(new InnerJoin(unionAll(plannodes.get(0)), unionAll(plannodes.get(1)))
.getJoined(BufferedPlanNode.class), "");
PlanNode innerJoin = new LoggingNode(new InnerJoin(unionAll(plannodes.get(0)), unionAll(plannodes.get(1))).getJoined(BufferedPlanNode.class), "");

for (int i = 2; i < plannodes.size(); i++) {
innerJoin = new LoggingNode(
new InnerJoin(innerJoin, unionAll(plannodes.get(i))).getJoined(BufferedPlanNode.class), "");
innerJoin = new LoggingNode(new InnerJoin(innerJoin, unionAll(plannodes.get(i))).getJoined(BufferedPlanNode.class), "");
}

ret = new LoggingNode(innerJoin, "");
} else {
throw new IllegalStateException("Should not get here!");

}

if (printPlans) {
Expand Down Expand Up @@ -157,10 +164,10 @@ public boolean requiresEvaluation(SailConnection addedStatements, SailConnection
}

return super.requiresEvaluation(addedStatements, removedStatements) || or.stream()
.flatMap(Collection::stream)
.map(p -> p.requiresEvaluation(addedStatements, removedStatements))
.reduce((a, b) -> a || b)
.orElse(false);
.flatMap(Collection::stream)
.map(p -> p.requiresEvaluation(addedStatements, removedStatements))
.reduce((a, b) -> a || b)
.orElse(false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,20 @@ interface FilterAttacher {
static public PlanNode getGenericSingleObjectPlan(ShaclSailConnection shaclSailConnection, NodeShape nodeShape,
FilterAttacher filterAttacher, PathPropertyShape pathPropertyShape, PlanNode overrideTargetNode) {
if (overrideTargetNode != null) {
PlanNode bulkedExternalInnerJoin = new LoggingNode(new BulkedExternalInnerJoin(overrideTargetNode,
shaclSailConnection, pathPropertyShape.path.getQuery("?a", "?c", null), false), "");

return new LoggingNode(
filterAttacher.attachFilter(bulkedExternalInnerJoin).getFalseNode(UnBufferedPlanNode.class), "");
PlanNode planNode;

if(pathPropertyShape.path == null){
planNode = new ModifyTuple(overrideTargetNode, t -> {
t.line.add(t.line.get(0));
return t;
});
}else{
planNode = new LoggingNode(new BulkedExternalInnerJoin(overrideTargetNode, shaclSailConnection, pathPropertyShape.path.getQuery("?a", "?c", null), false), "");
}


return new LoggingNode(filterAttacher.attachFilter(planNode).getFalseNode(UnBufferedPlanNode.class), "AAAAAA");
}

if(pathPropertyShape.path == null){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ public class ShaclSail extends NotifyingSailWrapper {
private List<NodeShape> nodeShapes = Collections.emptyList();

private static String SH_OR_UPDATE_QUERY;
private static String SH_OR_NODE_SHAPE_UPDATE_QUERY;
private static String IMPLICIT_TARGET_CLASS_NODE_SHAPE;
private static String IMPLICIT_TARGET_CLASS_PROPERTY_SHAPE;

Expand All @@ -157,7 +156,6 @@ public class ShaclSail extends NotifyingSailWrapper {
static {
try {
SH_OR_UPDATE_QUERY = resourceAsString("shacl-sparql-inference/sh_or.rq");
SH_OR_NODE_SHAPE_UPDATE_QUERY = resourceAsString("shacl-sparql-inference/sh_or_node_shape.rq");
IMPLICIT_TARGET_CLASS_NODE_SHAPE = resourceAsString(
"shacl-sparql-inference/implicitTargetClassNodeShape.rq");
IMPLICIT_TARGET_CLASS_PROPERTY_SHAPE = resourceAsString(
Expand Down Expand Up @@ -337,7 +335,6 @@ private void runInferencingSparqlQueries(SailRepositoryConnection shaclSailConne
shaclSailConnection.prepareUpdate(IMPLICIT_TARGET_CLASS_PROPERTY_SHAPE).execute();
shaclSailConnection.prepareUpdate(IMPLICIT_TARGET_CLASS_NODE_SHAPE).execute();
shaclSailConnection.prepareUpdate(SH_OR_UPDATE_QUERY).execute();
shaclSailConnection.prepareUpdate(SH_OR_NODE_SHAPE_UPDATE_QUERY).execute();
currentSize = shaclSailConnection.size();
} while (prevSize != currentSize);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ abstract public class AbstractShaclTest {
"test-cases/or/class",
"test-cases/or/datatype2",
"test-cases/or/minCountDifferentPath",
"test-cases/or/nodeKindValidateTarget",
"test-cases/deactivated/nodeshape",
"test-cases/deactivated/or",
"test-cases/deactivated/propertyshape"
Expand Down Expand Up @@ -169,7 +170,7 @@ static void runTestCase(String shaclPath, String dataPath, ExpectedResult expect
System.out.println(shaclFile);
ShaclSail shaclSail = new ShaclSail(new MemoryStore());
shaclSail.setLogValidationPlans(true);
// shaclSail.setParallelValidation(false);
shaclSail.setCacheSelectNodes(false);
SailRepository shaclRepository = new SailRepository(shaclSail);
shaclRepository.init();
Utils.loadShapeData(shaclRepository, shaclFile);
Expand Down Expand Up @@ -243,6 +244,8 @@ static void runTestCaseSingleTransaction(String shaclPath, String dataPath, Expe
ShaclSail shaclSail = new ShaclSail(new MemoryStore());
SailRepository shaclRepository = new SailRepository(shaclSail);
shaclSail.setLogValidationPlans(true);
shaclSail.setCacheSelectNodes(false);

shaclRepository.init();
Utils.loadShapeData(shaclRepository, shaclPath + "shacl.ttl");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
PREFIX ex: <http://example.com/ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

delete{
?a sh:or ?or.
}
insert {

?a sh:property [ sh:or ?or ] .
INSERT DATA {

} where {
ex:validPerson1 ex:knows "hello" .

?a a sh:NodeShape ;
sh:or ?or .

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
PREFIX ex: <http://example.com/ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

INSERT DATA {

ex:validPerson1 ex:knows 3 .

[] ex:knows ex:validPerson2 .
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
PREFIX ex: <http://example.com/ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

INSERT DATA {

ex:validPerson1 ex:knows 3 .
ex:validPerson1 ex:knows [] .
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
PREFIX ex: <http://example.com/ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

INSERT DATA {

ex:validPerson1 ex:knows 3 .
ex:validPerson1 ex:knows [] .
[] ex:knows ex:validPerson2 .
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@base <http://example.com/ns> .
@prefix ex: <http://example.com/ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:PersonShape
a sh:NodeShape ;
sh:targetObjectsOf ex:knows ;
sh:or ([sh:nodeKind sh:IRI] [sh:nodeKind sh:BlankNode]) .

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
PREFIX ex: <http://example.com/ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

INSERT DATA {

ex:validPerson1 ex:knows ex:validPerson1 .

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
PREFIX ex: <http://example.com/ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

INSERT DATA {

[] ex:knows [] .

}

0 comments on commit 232a70b

Please sign in to comment.