@Override
protected Optional<PredicateLevelProposal> proposePerPredicate(InnerJoinNode joinNode, ImmutableCollection<DataNode> initialNodes,
AtomPredicate predicate, DBMetadata dbMetadata,
ImmutableList<Variable> priorityVariables,
IntermediateQuery query)
throws AtomUnificationException {
if (initialNodes.size() < 2)
return Optional.empty();
RelationID relationId = Relation2Predicate.createRelationFromPredicateName(
dbMetadata.getQuotedIDFactory(), predicate);
DatabaseRelationDefinition databaseRelation = dbMetadata.getDatabaseRelation(relationId);
if (databaseRelation == null)
return Optional.empty();
ImmutableMap<FunctionalDependency, ImmutableCollection<Collection<DataNode>>> constraintNodeMap =
databaseRelation.getOtherFunctionalDependencies().stream()
.collect(ImmutableCollectors.toMap(
c -> c,
c -> groupDataNodesPerConstraint(c, initialNodes)));
ImmutableSet<Variable> requiredAndCooccuringVariables = extractRequiredAndCooccuringVariables(query, joinNode);
ImmutableSet<DataNode> nodesToRemove = selectNodesToRemove(requiredAndCooccuringVariables,
constraintNodeMap, predicate);
ImmutableList<ImmutableSubstitution<VariableOrGroundTerm>> dependentUnifiers = extractDependentUnifiers(
databaseRelation, constraintNodeMap, nodesToRemove);
return (dependentUnifiers.isEmpty() && nodesToRemove.isEmpty())
? Optional.empty()
: Optional.of(new PredicateLevelProposal(dependentUnifiers, nodesToRemove));
}