Skip to content

Commit

Permalink
GH-5130 zeroOrMorePath and oneOrMorePath mostly implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
hmottestad committed Nov 21, 2024
1 parent 44bbbbd commit cc37d21
Show file tree
Hide file tree
Showing 173 changed files with 2,485 additions and 1,968 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ public static List<IRI> getSupportedShaclPredicates() {
SHACL.TARGET_PROP,
SHACL.INVERSE_PATH,
SHACL.ALTERNATIVE_PATH,
SHACL.ONE_OR_MORE_PATH,
SHACL.ZERO_OR_MORE_PATH,
SHACL.NODE,
SHACL.QUALIFIED_MAX_COUNT,
SHACL.QUALIFIED_MIN_COUNT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.sail.SailConnection;
import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.sail.shacl.ast.Shape;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

import org.eclipse.rdf4j.model.Namespace;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.sail.shacl.ast.paths.Path;
import org.eclipse.rdf4j.sail.shacl.ast.targets.EffectiveTarget;
import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
Expand Down Expand Up @@ -337,8 +336,10 @@ public String getNamespacesForSparql() {
return ShaclPrefixParser.toSparqlPrefixes(namespaces);
}

public Stream<EffectiveTarget.StatementsAndMatcher> getRoot(ConnectionsGroup connectionsGroup, Resource[] dataGraph,
Path path, StatementMatcher currentStatementMatcher, List<Statement> currentStatements) {
public Stream<EffectiveTarget.SubjectObjectAndMatcher> getRoot(ConnectionsGroup connectionsGroup,
Resource[] dataGraph,
Path path, StatementMatcher currentStatementMatcher,
List<EffectiveTarget.SubjectObjectAndMatcher.SubjectObject> currentStatements) {
assert traceBackFunction != null;
return traceBackFunction.getRoot(connectionsGroup, dataGraph, path, currentStatementMatcher, currentStatements);
}
Expand Down Expand Up @@ -411,12 +412,12 @@ public int hashCode() {

public interface TraceBack {

Stream<EffectiveTarget.StatementsAndMatcher> getRoot(
Stream<EffectiveTarget.SubjectObjectAndMatcher> getRoot(
ConnectionsGroup connectionsGroup,
Resource[] dataGraph,
Path path,
StatementMatcher currentStatementMatcher,
List<Statement> currentStatements);
List<EffectiveTarget.SubjectObjectAndMatcher.SubjectObject> currentStatements);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ static PlanNode getAllTargetsIncludingThoseAddedByPath(ConnectionsGroup connecti
null);

allTargets = UnionNode.getInstance(connectionsGroup, addedTargets.getPlanNode(), addedByPath);

allTargets = Unique.getInstance(new TrimToTarget(allTargets, connectionsGroup), false, connectionsGroup);

return allTargets;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Resource[]

}

return Unique.getInstance(allTargetsPlan, false, connectionsGroup);
return Unique.getInstance(new TrimToTarget(allTargetsPlan, connectionsGroup), false, connectionsGroup);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,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.AbstractBulkJoinPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AllTargetsPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BufferedPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalInnerJoin;
Expand Down Expand Up @@ -135,7 +136,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getPreviousStateConnection(),
b -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

top = UnionNode.getInstance(connectionsGroup, top, bulkedExternalInnerJoin);

Expand Down Expand Up @@ -218,7 +219,7 @@ private PlanNode getPlanNodeForOverrideTargetNode(ConnectionsGroup connectionsGr
Set.of()),
false, null,
BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);
planNode = connectionsGroup.getCachedNodeFor(planNode);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.AbstractBulkJoinPlanNode;
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;
Expand Down Expand Up @@ -171,7 +172,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
false,
null,
BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

if (connectionsGroup.getAddedStatements() != null) {
// filter by type against the added statements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.ValidationQuery;
import org.eclipse.rdf4j.sail.shacl.ast.paths.Path;
import org.eclipse.rdf4j.sail.shacl.ast.paths.SimplePath;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AbstractBulkJoinPlanNode;
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.ExternalFilterByQuery;
Expand Down Expand Up @@ -192,7 +193,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
false,
null,
BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

StatementMatcher.Variable<Value> subjectVariable = stableRandomVariableProvider.next();
StatementMatcher.Variable<Value> predicateVariable = stableRandomVariableProvider.next();
Expand Down Expand Up @@ -317,7 +318,10 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
}
return validationTuple;
},
connectionsGroup);
connectionsGroup,
List.of(AbstractBulkJoinPlanNode.DEFAULT_VARS.get(0), AbstractBulkJoinPlanNode.DEFAULT_VARS.get(1),
predicateVariable)
);

return bulkedExternalInnerJoin;
}
Expand Down Expand Up @@ -529,11 +533,6 @@ private String getFilter(StatementMatcher.Variable<Value> target,
return sparqlFragment.getFragment();
}

@Override
public ValidationApproach getPreferredValidationApproach(ConnectionsGroup connectionsGroup) {
return super.getPreferredValidationApproach(connectionsGroup);
}

@Override
public ValidationApproach getOptimalBulkValidationApproach() {
return ValidationApproach.SPARQL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher;
import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher.Variable;
import org.eclipse.rdf4j.sail.shacl.ast.paths.Path;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AbstractBulkJoinPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalLeftOuterJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EmptyNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.GroupByFilter;
Expand Down Expand Up @@ -113,7 +114,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

PlanNode invalidTargets = new GroupByFilter(joined, group -> {
return group.stream().map(ValidationTuple::getValue).noneMatch(hasValueIn::contains);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,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.AbstractBulkJoinPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalLeftOuterJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EmptyNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.GroupByFilter;
Expand Down Expand Up @@ -98,16 +99,18 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
EffectiveTarget.Extend.left, false, null);

addedTargets = UnionNode.getInstance(connectionsGroup, addedByPath, addedTargets);
addedTargets = Unique.getInstance(addedTargets, false, connectionsGroup);
}

addedTargets = Unique.getInstance(new TrimToTarget(addedTargets, connectionsGroup), false,
connectionsGroup);

PlanNode joined = new BulkedExternalLeftOuterJoin(addedTargets, connectionsGroup.getBaseConnection(),
validationSettings.getDataGraph(),
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()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

PlanNode invalidTargets = new GroupByFilter(joined, group -> {
return group
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,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.AbstractBulkJoinPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalInnerJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalLeftOuterJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EmptyNode;
Expand Down Expand Up @@ -113,7 +114,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
false,
null,
BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);
} else {
relevantTargetsWithPath = new BulkedExternalLeftOuterJoin(
mergeNode,
Expand All @@ -126,7 +127,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);
}

relevantTargetsWithPath = connectionsGroup.getCachedNodeFor(relevantTargetsWithPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher;
import org.eclipse.rdf4j.sail.shacl.ast.ValidationApproach;
import org.eclipse.rdf4j.sail.shacl.ast.ValidationQuery;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AbstractBulkJoinPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalLeftOuterJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EmptyNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.GroupByCountFilter;
Expand Down Expand Up @@ -82,6 +83,10 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode addedByPath = getTargetChain().getPath()
.get()
.getAnyAdded(connectionsGroup, validationSettings.getDataGraph(), null);

// we don't need to compress here because we are anyway going to trim to target later on
addedByPath = Unique.getInstance(addedByPath, false, connectionsGroup);

LeftOuterJoin leftOuterJoin = new LeftOuterJoin(target, addedByPath, connectionsGroup);
target = new GroupByCountFilter(leftOuterJoin, count -> count < minCount, connectionsGroup);
}
Expand All @@ -97,6 +102,10 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
PlanNode addedByPath = getTargetChain().getPath()
.get()
.getAnyAdded(connectionsGroup, validationSettings.getDataGraph(), null);

// we don't need to compress here because we are anyway going to trim to target later on
addedByPath = Unique.getInstance(addedByPath, false, connectionsGroup);

LeftOuterJoin leftOuterJoin = new LeftOuterJoin(target, addedByPath, connectionsGroup);
target = new GroupByCountFilter(leftOuterJoin, count -> count < minCount, connectionsGroup);
}
Expand All @@ -110,7 +119,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
connectionsGroup.getRdfsSubClassOfReasoner(), stableRandomVariableProvider, Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

relevantTargetsWithPath = connectionsGroup.getCachedNodeFor(relevantTargetsWithPath);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.Shape;
import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher;
import org.eclipse.rdf4j.sail.shacl.ast.ValidationQuery;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AbstractBulkJoinPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalLeftOuterJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.GroupByCountFilter;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.LeftOuterJoin;
Expand Down Expand Up @@ -182,7 +183,7 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

return new TupleMapper(relevantTargetsWithPath, t -> {
List<Value> targetChain = t.getTargetChain(true);
Expand Down Expand Up @@ -226,7 +227,7 @@ 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()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

invalid = new NotValuesIn(allTargetsPlan, invalid, connectionsGroup);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.eclipse.rdf4j.sail.shacl.ast.Shape;
import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher;
import org.eclipse.rdf4j.sail.shacl.ast.ValidationQuery;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AbstractBulkJoinPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.AllTargetsPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalLeftOuterJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.GroupByCountFilter;
Expand Down Expand Up @@ -189,7 +190,7 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

return new TupleMapper(relevantTargetsWithPath, t -> {
List<Value> targetChain = t.getTargetChain(true);
Expand Down Expand Up @@ -240,7 +241,7 @@ public PlanNode negated(ConnectionsGroup connectionsGroup, ValidationSettings va
Set.of()),
(b) -> new ValidationTuple(b.getValue("a"), b.getValue("c"), scope, true,
validationSettings.getDataGraph()),
connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);
}

invalid = new NotValuesIn(allTargetsPlan, invalid, connectionsGroup);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,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.AbstractBulkJoinPlanNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.BulkedExternalInnerJoin;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EmptyNode;
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.InnerJoin;
Expand Down Expand Up @@ -142,7 +143,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
null,
BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),

connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

PlanNode nonUniqueTargetLang = new NonUniqueTargetLang(relevantTargetsWithPath, connectionsGroup);
return Unique.getInstance(new TrimToTarget(nonUniqueTargetLang, connectionsGroup), false, connectionsGroup);
Expand Down Expand Up @@ -189,8 +190,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
false,
null,
BulkedExternalInnerJoin.getMapper("a", "c", scope, validationSettings.getDataGraph()),

connectionsGroup);
connectionsGroup, AbstractBulkJoinPlanNode.DEFAULT_VARS);

PlanNode nonUniqueTargetLang = new NonUniqueTargetLang(relevantTargetsWithPath, connectionsGroup);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.vocabulary.SHACL;
import org.eclipse.rdf4j.sail.shacl.ast.ShaclAstLists;
import org.eclipse.rdf4j.sail.shacl.ast.SparqlFragment;
Expand Down Expand Up @@ -128,12 +127,12 @@ public SparqlFragment getTargetQueryFragment(StatementMatcher.Variable subject,

return SparqlFragment.union(sparqlFragments,
(ConnectionsGroup connectionsGroup, Resource[] dataGraph, Path path,
StatementMatcher currentStatementMatcher, List<Statement> currentStatements) -> {

StatementMatcher currentStatementMatcher,
List<EffectiveTarget.SubjectObjectAndMatcher.SubjectObject> currentStatements) -> {
return sparqlFragments.stream()
.flatMap(sparqlFragment -> sparqlFragment.getRoot(connectionsGroup, dataGraph, path,
currentStatementMatcher, currentStatements))
.filter(EffectiveTarget.StatementsAndMatcher::hasStatements);
.filter(EffectiveTarget.SubjectObjectAndMatcher::hasStatements);

}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public SparqlFragment getTargetQueryFragment(StatementMatcher.Variable subject,
StatementMatcher.StableRandomVariableProvider stableRandomVariableProvider, Set<String> inheritedVarNames) {

return path.getTargetQueryFragment(object, subject, rdfsSubClassOfReasoner,
stableRandomVariableProvider, Set.of());
stableRandomVariableProvider, inheritedVarNames);

}

Expand Down
Loading

0 comments on commit cc37d21

Please sign in to comment.