use of org.apache.jackrabbit.spi.commons.query.qom.EquiJoinConditionImpl in project jackrabbit by apache.
the class Join method create.
/**
* Creates a new join result.
*
* @param left the left query hits.
* @param right the right query hits.
* @param joinType the join type.
* @param condition the QOM join condition.
* @param reader the index reader.
* @param resolver the hierarchy resolver.
* @param nsMappings namespace mappings of this index
* @param hmgr the hierarchy manager of the workspace.
* @return the join result.
* @throws IOException if an error occurs while executing the join.
*/
public static Join create(final MultiColumnQueryHits left, final MultiColumnQueryHits right, final JoinType joinType, final JoinConditionImpl condition, final IndexReader reader, final HierarchyResolver resolver, final NamespaceMappings nsMappings, final HierarchyManager hmgr) throws IOException {
try {
return (Join) condition.accept(new DefaultQOMTreeVisitor() {
private boolean isInner = JoinType.INNER == joinType;
private MultiColumnQueryHits outer;
private int outerIdx;
public Object visit(DescendantNodeJoinConditionImpl node, Object data) throws Exception {
MultiColumnQueryHits ancestor = getSourceWithName(node.getAncestorSelectorQName(), left, right);
MultiColumnQueryHits descendant = getSourceWithName(node.getDescendantSelectorQName(), left, right);
Condition c;
if (isInner || descendant == left && JoinType.LEFT == joinType || descendant == right && JoinType.RIGHT == joinType) {
// also applies to inner join
// assumption: DescendantNodeJoin is more
// efficient than AncestorNodeJoin, TODO: verify
outer = descendant;
outerIdx = getIndex(outer, node.getDescendantSelectorQName());
c = new DescendantNodeJoin(ancestor, node.getAncestorSelectorQName(), reader, resolver);
} else {
// left == ancestor
outer = ancestor;
outerIdx = getIndex(outer, node.getAncestorSelectorQName());
c = new AncestorNodeJoin(descendant, node.getDescendantSelectorQName(), reader, resolver);
}
return new Join(outer, outerIdx, isInner, c);
}
public Object visit(EquiJoinConditionImpl node, Object data) throws Exception {
MultiColumnQueryHits src1 = getSourceWithName(node.getSelector1QName(), left, right);
MultiColumnQueryHits src2 = getSourceWithName(node.getSelector2QName(), left, right);
MultiColumnQueryHits inner;
Name innerName;
Name innerPropName;
Name outerPropName;
if (isInner || src1 == left && JoinType.LEFT == joinType || src1 == right && JoinType.RIGHT == joinType) {
outer = src1;
outerIdx = getIndex(outer, node.getSelector1QName());
inner = src2;
innerName = node.getSelector2QName();
innerPropName = node.getProperty2QName();
outerPropName = node.getProperty1QName();
} else {
outer = src2;
outerIdx = getIndex(outer, node.getSelector2QName());
inner = src1;
innerName = node.getSelector1QName();
innerPropName = node.getProperty1QName();
outerPropName = node.getProperty2QName();
}
Condition c = new EquiJoin(inner, getIndex(inner, innerName), nsMappings, reader, innerPropName, outerPropName);
return new Join(outer, outerIdx, isInner, c);
}
public Object visit(ChildNodeJoinConditionImpl node, Object data) throws Exception {
MultiColumnQueryHits child = getSourceWithName(node.getChildSelectorQName(), left, right);
MultiColumnQueryHits parent = getSourceWithName(node.getParentSelectorQName(), left, right);
Condition c;
if (child == left && JoinType.LEFT == joinType || child == right && JoinType.RIGHT == joinType) {
outer = child;
outerIdx = getIndex(outer, node.getChildSelectorQName());
c = new ChildNodeJoin(parent, reader, resolver, node);
} else {
// also applies to inner joins
// assumption: ParentNodeJoin is more efficient than
// ChildNodeJoin, TODO: verify
outer = parent;
outerIdx = getIndex(outer, node.getParentSelectorQName());
c = new ParentNodeJoin(child, reader, resolver, node);
}
return new Join(outer, outerIdx, isInner, c);
}
public Object visit(SameNodeJoinConditionImpl node, Object data) throws Exception {
MultiColumnQueryHits src1 = getSourceWithName(node.getSelector1QName(), left, right);
MultiColumnQueryHits src2 = getSourceWithName(node.getSelector2QName(), left, right);
Condition c;
if (isInner || src1 == left && JoinType.LEFT == joinType || src1 == right && JoinType.RIGHT == joinType) {
outer = src1;
outerIdx = getIndex(outer, node.getSelector1QName());
Path selector2Path = node.getSelector2QPath();
if (selector2Path == null || (selector2Path.getLength() == 1 && selector2Path.denotesCurrent())) {
c = new SameNodeJoin(src2, node.getSelector2QName(), reader);
} else {
c = new DescendantPathNodeJoin(src2, node.getSelector2QName(), node.getSelector2QPath(), hmgr);
}
} else {
outer = src2;
outerIdx = getIndex(outer, node.getSelector2QName());
Path selector2Path = node.getSelector2QPath();
if (selector2Path == null || (selector2Path.getLength() == 1 && selector2Path.denotesCurrent())) {
c = new SameNodeJoin(src1, node.getSelector1QName(), reader);
} else {
c = new AncestorPathNodeJoin(src1, node.getSelector1QName(), node.getSelector2QPath(), hmgr);
}
}
return new Join(outer, outerIdx, isInner, c);
}
}, null);
} catch (IOException e) {
throw e;
} catch (Exception e) {
IOException ex = new IOException(e.getMessage());
ex.initCause(e);
throw ex;
}
}
Aggregations