List<Triple> newPatterns = new ArrayList<Triple>(joinedTriplePatterns);
newPatterns.add(pattern);
List<NodeRelation> newRelations = new ArrayList<NodeRelation>(joinedTripleRelations);
newRelations.add(relation);
VariableConstraints nodeSets = new VariableConstraints();
for (int i = 0; i < newPatterns.size(); i++) {
Triple t = (Triple) newPatterns.get(i);
NodeRelation r = newRelations.get(i);
if (useAllOptimizations) {
/*
* Before adding a NodeMaker, try to adopt aliases from existing NodeMakers
* in order to prevent unnecessary self-joins (#2798308)
*/
// This failed when originalName had more than 1 alias r.baseRelation (fixed, GM)
List<String> names = new ArrayList<String>();
if (t.getSubject().isVariable())
names.add(t.getSubject().getName());
if (t.getPredicate().isVariable())
names.add(t.getPredicate().getName());
if (t.getObject().isVariable())
names.add(t.getObject().getName());
for (String name: names) {
Var nameVar = Var.alloc(name);
NodeMaker n = (NodeMaker) nodeSets.toMap().get(nameVar);
if (n != null/* && n instanceof TypedNodeMaker*/) {
AttributeSet attributes = AttributeSet.createFrom(n);
/*
* If we would set an alias to this table...
*/
if (attributes != null) {
AliasMap amap = (AliasMap)(nodeSets.relationAliases().get(nameVar));
RelationName originalName = amap.originalOf(attributes.relationName);
if (r.baseRelation().aliases().hasAlias(originalName)) {
/*
* ... and indexes are in place to guarantee uniqueness of the attribute combination...
*/
if (isUnique(r.baseRelation().database(), originalName, attributes.attributeNames)) {
if (t.getSubject().isVariable() && t.getSubject().getName().equals(name)) {
// ... then first find the right relation name...
AttributeSet existing = AttributeSet.createFrom(r.nodeMaker(TripleRelation.SUBJECT));
if (existing != null && existing.attributeNames.equals(attributes.attributeNames)) {
// ... then apply it
r = r.renameSingleRelation(existing.relationName, attributes.relationName);
newRelations.set(i, r);
}
}
if (t.getPredicate().isVariable() && t.getPredicate().getName().equals(name)) {
// ... then first find the right relation name...
AttributeSet existing = AttributeSet.createFrom(r.nodeMaker(TripleRelation.PREDICATE));
if (existing != null && existing.attributeNames.equals(attributes.attributeNames)) {
// ... then apply it
r = r.renameSingleRelation(existing.relationName, attributes.relationName);
newRelations.set(i, r);
}
}
if (t.getObject().isVariable() && t.getObject().getName().equals(name)) {
// ... then first find the right relation name...
AttributeSet existing = AttributeSet.createFrom(r.nodeMaker(TripleRelation.OBJECT));
if (existing != null && existing.attributeNames.equals(attributes.attributeNames)) {
// ... then apply it
r = r.renameSingleRelation(existing.relationName, attributes.relationName);
newRelations.set(i, r);
}
}
}
}
}
}
}
}
if (t.getObject().isVariable()) {
List<RelationName> relationNames = getRelationNames(
r.nodeMaker(TripleRelation.OBJECT));
Set<Alias> aliases = new HashSet<Alias>();
for (RelationName rname: relationNames) {
if (r.baseRelation().aliases().isAlias(rname))
aliases.add(new AliasMap.Alias(r.baseRelation().aliases().originalOf(rname), rname));
}
nodeSets.add(Var.alloc(t.getObject()), r.nodeMaker(TripleRelation.OBJECT), new AliasMap(aliases));
}
if (t.getPredicate().isVariable()) {
List<RelationName> relationNames = getRelationNames(
r.nodeMaker(TripleRelation.PREDICATE));
Set<Alias> aliases = new HashSet<Alias>();
for (RelationName rname: relationNames) {
if (r.baseRelation().aliases().isAlias(rname))
aliases.add(new AliasMap.Alias(r.baseRelation().aliases().originalOf(rname), rname));
}
nodeSets.add(Var.alloc(t.getPredicate()), r.nodeMaker(TripleRelation.PREDICATE), new AliasMap(aliases));
}
if (t.getSubject().isVariable()) {
List<RelationName> relationNames = getRelationNames(
r.nodeMaker(TripleRelation.SUBJECT));
Set<Alias> aliases = new HashSet<Alias>();
for (RelationName rname: relationNames) {
if (r.baseRelation().aliases().isAlias(rname))
aliases.add(new AliasMap.Alias(r.baseRelation().aliases().originalOf(rname), rname));
}
nodeSets.add(Var.alloc(t.getSubject()), r.nodeMaker(TripleRelation.SUBJECT), new AliasMap(aliases));
}
}
if (!nodeSets.satisfiable()) {
return null;
}
return new TripleRelationJoiner(nodeSets, newPatterns, newRelations, useAllOptimizations);
}