Search in sources :

Example 1 with MultiColumnQueryHits

use of org.apache.jackrabbit.core.query.lucene.MultiColumnQueryHits 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;
    }
}
Also used : Path(org.apache.jackrabbit.spi.Path) MultiColumnQueryHits(org.apache.jackrabbit.core.query.lucene.MultiColumnQueryHits) DefaultQOMTreeVisitor(org.apache.jackrabbit.spi.commons.query.qom.DefaultQOMTreeVisitor) DescendantNodeJoinConditionImpl(org.apache.jackrabbit.spi.commons.query.qom.DescendantNodeJoinConditionImpl) IOException(java.io.IOException) ChildNodeJoinConditionImpl(org.apache.jackrabbit.spi.commons.query.qom.ChildNodeJoinConditionImpl) IOException(java.io.IOException) Name(org.apache.jackrabbit.spi.Name) SameNodeJoinConditionImpl(org.apache.jackrabbit.spi.commons.query.qom.SameNodeJoinConditionImpl) EquiJoinConditionImpl(org.apache.jackrabbit.spi.commons.query.qom.EquiJoinConditionImpl)

Aggregations

IOException (java.io.IOException)1 MultiColumnQueryHits (org.apache.jackrabbit.core.query.lucene.MultiColumnQueryHits)1 Name (org.apache.jackrabbit.spi.Name)1 Path (org.apache.jackrabbit.spi.Path)1 ChildNodeJoinConditionImpl (org.apache.jackrabbit.spi.commons.query.qom.ChildNodeJoinConditionImpl)1 DefaultQOMTreeVisitor (org.apache.jackrabbit.spi.commons.query.qom.DefaultQOMTreeVisitor)1 DescendantNodeJoinConditionImpl (org.apache.jackrabbit.spi.commons.query.qom.DescendantNodeJoinConditionImpl)1 EquiJoinConditionImpl (org.apache.jackrabbit.spi.commons.query.qom.EquiJoinConditionImpl)1 SameNodeJoinConditionImpl (org.apache.jackrabbit.spi.commons.query.qom.SameNodeJoinConditionImpl)1