diff --git a/src/main/java/be/ugent/rml/MappingOptimizer.java b/src/main/java/be/ugent/rml/MappingOptimizer.java index 70be3760..3b4b9ac2 100644 --- a/src/main/java/be/ugent/rml/MappingOptimizer.java +++ b/src/main/java/be/ugent/rml/MappingOptimizer.java @@ -64,88 +64,94 @@ private void eliminateSelfJoins() { for (Quad refObjectMapQuad : refObjectMapsQuads) { Term parentTriplesMap = refObjectMapQuad.getObject(); Term childObjectMap = refObjectMapQuad.getSubject(); - Term parentLogicalSource = Utils.getObjectsFromQuads(rmlStore.getQuads(parentTriplesMap, new NamedNode(NAMESPACES.RML2 + "logicalSource"), null)).get(0); - Term childPredicateObjectMap = Utils.getSubjectsFromQuads(rmlStore.getQuads(null, new NamedNode(NAMESPACES.RML2 + "objectMap"), childObjectMap)).get(0); - Term childTriplesMap = Utils.getSubjectsFromQuads(rmlStore.getQuads(null, new NamedNode(NAMESPACES.RML2 + "predicateObjectMap"), childPredicateObjectMap)).get(0); - Term childLogicalSource = Utils.getObjectsFromQuads(rmlStore.getQuads(childTriplesMap, new NamedNode(NAMESPACES.RML2 + "logicalSource"), null)).get(0); - // check if the logical sources are the same - if (childLogicalSource.equals(parentLogicalSource)) { - List joinConditions = Utils.getObjectsFromQuads(rmlStore.getQuads(childObjectMap, new NamedNode(NAMESPACES.RML2 + "joinCondition"), null)); + try { + Term parentLogicalSource = Utils.getObjectsFromQuads(rmlStore.getQuads(parentTriplesMap, new NamedNode(NAMESPACES.RML2 + "logicalSource"), null)).get(0); + Term childPredicateObjectMap = Utils.getSubjectsFromQuads(rmlStore.getQuads(null, new NamedNode(NAMESPACES.RML2 + "objectMap"), childObjectMap)).get(0); + Term childTriplesMap = Utils.getSubjectsFromQuads(rmlStore.getQuads(null, new NamedNode(NAMESPACES.RML2 + "predicateObjectMap"), childPredicateObjectMap)).get(0); + Term childLogicalSource = Utils.getObjectsFromQuads(rmlStore.getQuads(childTriplesMap, new NamedNode(NAMESPACES.RML2 + "logicalSource"), null)).get(0); - List parentSubjectMaps = Utils.getObjectsFromQuads(rmlStore.getQuads(parentTriplesMap, new NamedNode(NAMESPACES.RML2 + "subjectMap"), null)); - Term parentSubjectMap = null; - if (!parentSubjectMaps.isEmpty()) { - parentSubjectMap = parentSubjectMaps.get(0); - } + // check if the logical sources are the same + if (childLogicalSource.equals(parentLogicalSource)) { - boolean safeSelfJoinElimination = true; - - // if no join condition, we can safely eliminate the self-join - // else we need more checks - if (parentSubjectMap != null && !joinConditions.isEmpty()) { - // we can eliminate a self-join when all join conditions have equal references and all references for the parent subject or all reference for the related child triple come back in the join conditions - // 1. check if all join references are equal - List joinReferences = new ArrayList<>(); - for (Term joinCondition : joinConditions) { - String parent = getObjectsFromQuads(rmlStore.getQuads(joinCondition, new NamedNode(NAMESPACES.RML2 + "parent"), null)).get(0).getValue(); - String child = getObjectsFromQuads(rmlStore.getQuads(joinCondition, new NamedNode(NAMESPACES.RML2 + "child"), null)).get(0).getValue(); - if (child.equals(parent)) { - joinReferences.add(child); - } else { - safeSelfJoinElimination = false; - } + List joinConditions = Utils.getObjectsFromQuads(rmlStore.getQuads(childObjectMap, new NamedNode(NAMESPACES.RML2 + "joinCondition"), null)); + + List parentSubjectMaps = Utils.getObjectsFromQuads(rmlStore.getQuads(parentTriplesMap, new NamedNode(NAMESPACES.RML2 + "subjectMap"), null)); + Term parentSubjectMap = null; + if (!parentSubjectMaps.isEmpty()) { + parentSubjectMap = parentSubjectMaps.get(0); } - if (safeSelfJoinElimination) { - // 2. check if all references for the parent subject come back in the join conditions - boolean safeTerms = hasSafeReferences(parentSubjectMap, joinReferences); - if(!safeTerms) { - // if not all references for the parent subject come back in the join conditions, - // 3. check if all references for the related child terms come back in the join conditions - // 3.1 check child subject - List childSubjectMaps = Utils.getObjectsFromQuads(rmlStore.getQuads(parentTriplesMap, new NamedNode(NAMESPACES.RML2 + "subjectMap"), null)); - if(!childSubjectMaps.isEmpty()) { - safeTerms = hasSafeReferences(childSubjectMaps.get(0), joinReferences); + + boolean safeSelfJoinElimination = true; + + // if no join condition, we can safely eliminate the self-join + // else we need more checks + if (parentSubjectMap != null && !joinConditions.isEmpty()) { + // we can eliminate a self-join when all join conditions have equal references and all references for the parent subject or all reference for the related child triple come back in the join conditions + // 1. check if all join references are equal + List joinReferences = new ArrayList<>(); + for (Term joinCondition : joinConditions) { + String parent = getObjectsFromQuads(rmlStore.getQuads(joinCondition, new NamedNode(NAMESPACES.RML2 + "parent"), null)).get(0).getValue(); + String child = getObjectsFromQuads(rmlStore.getQuads(joinCondition, new NamedNode(NAMESPACES.RML2 + "child"), null)).get(0).getValue(); + if (child.equals(parent)) { + joinReferences.add(child); } else { - safeTerms = true; + safeSelfJoinElimination = false; } - //3.2 check child predicate (only make sense if the child subject was safe, otherwise we cannot eliminate the-self join) - if (safeTerms) { - List childPredicateMaps = Utils.getObjectsFromQuads(rmlStore.getQuads(childPredicateObjectMap, new NamedNode(NAMESPACES.RML2 + "predicateMap"), null)); - if(!childPredicateMaps.isEmpty()) { - safeTerms = hasSafeReferences(childPredicateMaps.get(0), joinReferences); + } + if (safeSelfJoinElimination) { + // 2. check if all references for the parent subject come back in the join conditions + boolean safeTerms = hasSafeReferences(parentSubjectMap, joinReferences); + if (!safeTerms) { + // if not all references for the parent subject come back in the join conditions, + // 3. check if all references for the related child terms come back in the join conditions + // 3.1 check child subject + List childSubjectMaps = Utils.getObjectsFromQuads(rmlStore.getQuads(parentTriplesMap, new NamedNode(NAMESPACES.RML2 + "subjectMap"), null)); + if (!childSubjectMaps.isEmpty()) { + safeTerms = hasSafeReferences(childSubjectMaps.get(0), joinReferences); + } else { + safeTerms = true; + } + //3.2 check child predicate (only make sense if the child subject was safe, otherwise we cannot eliminate the-self join) + if (safeTerms) { + List childPredicateMaps = Utils.getObjectsFromQuads(rmlStore.getQuads(childPredicateObjectMap, new NamedNode(NAMESPACES.RML2 + "predicateMap"), null)); + if (!childPredicateMaps.isEmpty()) { + safeTerms = hasSafeReferences(childPredicateMaps.get(0), joinReferences); + } } } - } - // 4. if parent subject or all child terms are safe, the self join can be eliminated, else not - if (!safeTerms) { - safeSelfJoinElimination = false; + // 4. if parent subject or all child terms are safe, the self join can be eliminated, else not + if (!safeTerms) { + safeSelfJoinElimination = false; + } } } - } - if (safeSelfJoinElimination) { - // now we rewrite the mapping file to eliminate the self-join - boolean termTypeAdded = false; - List parentSubjectMapQuads = rmlStore.getQuads(parentSubjectMap, null, null); - for (Quad parentSubjectMapQuad : parentSubjectMapQuads) { - Term predicate = parentSubjectMapQuad.getPredicate(); - if (predicate.equals(new NamedNode(NAMESPACES.FNML + "functionValue")) - || predicate.equals(new NamedNode(NAMESPACES.RML2 + "termType")) - || predicate.equals(new NamedNode(NAMESPACES.RML2 + "reference")) - || predicate.equals(new NamedNode(NAMESPACES.RML2 + "template")) - || predicate.equals(new NamedNode(NAMESPACES.RML2 + "constant"))) { - rmlStore.addQuad(childObjectMap, predicate, parentSubjectMapQuad.getObject()); + if (safeSelfJoinElimination) { + // now we rewrite the mapping file to eliminate the self-join + boolean termTypeAdded = false; + List parentSubjectMapQuads = rmlStore.getQuads(parentSubjectMap, null, null); + for (Quad parentSubjectMapQuad : parentSubjectMapQuads) { + Term predicate = parentSubjectMapQuad.getPredicate(); + if (predicate.equals(new NamedNode(NAMESPACES.FNML + "functionValue")) + || predicate.equals(new NamedNode(NAMESPACES.RML2 + "termType")) + || predicate.equals(new NamedNode(NAMESPACES.RML2 + "reference")) + || predicate.equals(new NamedNode(NAMESPACES.RML2 + "template")) + || predicate.equals(new NamedNode(NAMESPACES.RML2 + "constant"))) { + rmlStore.addQuad(childObjectMap, predicate, parentSubjectMapQuad.getObject()); + } + if (predicate.equals(new NamedNode(NAMESPACES.RML2 + "termType"))) { + termTypeAdded = true; + } } - if (predicate.equals(new NamedNode(NAMESPACES.RML2 + "termType"))) { - termTypeAdded = true; + rmlStore.removeQuads(childObjectMap, new NamedNode(NAMESPACES.RML2 + "parentTriplesMap"), parentTriplesMap); + if (!termTypeAdded) { + rmlStore.addQuad(childObjectMap, new NamedNode(NAMESPACES.RML2 + "termType"), new NamedNode(NAMESPACES.RML2 + "IRI")); } } - rmlStore.removeQuads(childObjectMap, new NamedNode(NAMESPACES.RML2 + "parentTriplesMap"), parentTriplesMap); - if (!termTypeAdded) { - rmlStore.addQuad(childObjectMap, new NamedNode(NAMESPACES.RML2 + "termType"), new NamedNode(NAMESPACES.RML2 + "IRI")); - } } + } catch (java.lang.IndexOutOfBoundsException e) { + continue; } } } diff --git a/src/main/java/be/ugent/rml/records/RecordsFactory.java b/src/main/java/be/ugent/rml/records/RecordsFactory.java index 69480fb1..a61bb6d2 100644 --- a/src/main/java/be/ugent/rml/records/RecordsFactory.java +++ b/src/main/java/be/ugent/rml/records/RecordsFactory.java @@ -73,7 +73,8 @@ public List createRecords(Term triplesMap, QuadStore rmlStore) throws Ex return getRecords(access, logicalSource, referenceFormulation, rmlStore); } else { - throw new Error("No Logical Source is found for " + triplesMap + ". Exactly one Logical Source is required per Triples Map."); + logger.error("No Logical Source is found for " + triplesMap + ". Exactly one Logical Source is required per Triples Map."); + return new ArrayList<>(); } }