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 == JOIN_TYPE_LEFT_OUTER
|| descendant == right && joinType == JOIN_TYPE_RIGHT_OUTER) {
// 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 == JOIN_TYPE_LEFT_OUTER
|| src1 == right && joinType == JOIN_TYPE_RIGHT_OUTER) {
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),
scs, 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 == JOIN_TYPE_LEFT_OUTER
|| child == right && joinType == JOIN_TYPE_RIGHT_OUTER) {
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 == JOIN_TYPE_LEFT_OUTER
|| src1 == right && joinType == JOIN_TYPE_RIGHT_OUTER) {
outer = src1;
outerIdx = getIndex(outer, node.getSelector1QName());