protected QueryBuilder createJoin( JoinCondition condition ) { // CROSS joins have a higher precedence, so we may need to adjust the existing left side in this case... if (type == JoinType.CROSS && source instanceof Join && ((Join)source).type() != JoinType.CROSS) { // A CROSS join follows a non-CROSS join, so the CROSS join becomes precendent ... Join left = (Join)source; Join cross = new Join(left.getRight(), type, rightSource, condition); source = new Join(left.getLeft(), left.type(), cross, left.getJoinCondition()); } else { // Otherwise, just create using usual precedence ... source = new Join(source, type, rightSource, condition); } return QueryBuilder.this; } }
@Override public void visit( Join join ) { strategy.visit(join); enqueue(join.getLeft()); enqueue(join.getJoinCondition()); enqueue(join.getRight()); visitNext(); }
protected boolean usesSelector( Join join, SelectorName selector ) { Source left = join.getLeft(); if (left instanceof Selector && selector.equals(((Selector)left).aliasOrName())) return true; if (left instanceof Join && usesSelector((Join)left, selector)) return true; Source right = join.getRight(); if (right instanceof Selector && selector.equals(((Selector)right).aliasOrName())) return true; if (right instanceof Join && usesSelector((Join)right, selector)) return true; return false; }
protected Join join( Source left, JoinType joinType, Source right, JoinCondition joinCondition ) { return new Join(left, joinType, right, joinCondition); }
@Override public String getJoinType() { switch (type()) { case CROSS: return QueryObjectModelConstants.JCR_JOIN_TYPE_CROSS; case INNER: return QueryObjectModelConstants.JCR_JOIN_TYPE_INNER; case FULL_OUTER: return QueryObjectModelConstants.JCR_JOIN_TYPE_FULL_OUTER; case LEFT_OUTER: return QueryObjectModelConstants.JCR_JOIN_TYPE_LEFT_OUTER; case RIGHT_OUTER: return QueryObjectModelConstants.JCR_JOIN_TYPE_RIGHT_OUTER; } assert false; return null; }
@Override public void visit( Join join ) { strategy.visit(join); enqueue(join.getLeft()); enqueue(join.getJoinCondition()); enqueue(join.getRight()); visitNext(); }
protected boolean usesSelector( Join join, SelectorName selector ) { Source left = join.getLeft(); if (left instanceof Selector && selector.equals(((Selector)left).aliasOrName())) return true; if (left instanceof Join && usesSelector((Join)left, selector)) return true; Source right = join.getRight(); if (right instanceof Selector && selector.equals(((Selector)right).aliasOrName())) return true; if (right instanceof Join && usesSelector((Join)right, selector)) return true; return false; }
protected Join join( Source left, JoinType joinType, Source right, JoinCondition joinCondition ) { return new Join(left, joinType, right, joinCondition); }
@Override public String getJoinType() { switch (type()) { case CROSS: return QueryObjectModelConstants.JCR_JOIN_TYPE_CROSS; case INNER: return QueryObjectModelConstants.JCR_JOIN_TYPE_INNER; case FULL_OUTER: return QueryObjectModelConstants.JCR_JOIN_TYPE_FULL_OUTER; case LEFT_OUTER: return QueryObjectModelConstants.JCR_JOIN_TYPE_LEFT_OUTER; case RIGHT_OUTER: return QueryObjectModelConstants.JCR_JOIN_TYPE_RIGHT_OUTER; } assert false; return null; }
protected QueryBuilder createJoin( JoinCondition condition ) { // CROSS joins have a higher precedence, so we may need to adjust the existing left side in this case... if (type == JoinType.CROSS && source instanceof Join && ((Join)source).type() != JoinType.CROSS) { // A CROSS join follows a non-CROSS join, so the CROSS join becomes precendent ... Join left = (Join)source; Join cross = new Join(left.getRight(), type, rightSource, condition); source = new Join(left.getLeft(), left.type(), cross, left.getJoinCondition()); } else { // Otherwise, just create using usual precedence ... source = new Join(source, type, rightSource, condition); } return QueryBuilder.this; } }
@Override public Join join( javax.jcr.query.qom.Source left, javax.jcr.query.qom.Source right, String joinType, javax.jcr.query.qom.JoinCondition joinCondition ) { Source leftSource = CheckArg.getInstanceOf(left, Source.class, "left"); Source rightSource = CheckArg.getInstanceOf(right, Source.class, "right"); JoinCondition jcrJoinCondition = CheckArg.getInstanceOf(joinCondition, JoinCondition.class, "joinCondition"); CheckArg.isNotEmpty(joinType, "joinType"); joinType = joinType.trim(); JoinType type = null; if (QueryObjectModelConstants.JCR_JOIN_TYPE_CROSS.equals(joinType)) type = JoinType.CROSS; else if (QueryObjectModelConstants.JCR_JOIN_TYPE_INNER.equals(joinType)) type = JoinType.INNER; else if (QueryObjectModelConstants.JCR_JOIN_TYPE_FULL_OUTER.equals(joinType)) type = JoinType.FULL_OUTER; else if (QueryObjectModelConstants.JCR_JOIN_TYPE_LEFT_OUTER.equals(joinType)) type = JoinType.LEFT_OUTER; else if (QueryObjectModelConstants.JCR_JOIN_TYPE_RIGHT_OUTER.equals(joinType)) type = JoinType.RIGHT_OUTER; if (type == null) { throw new IllegalArgumentException("Unknown or unsupported join type: " + joinType); } return new Join(leftSource, type, rightSource, jcrJoinCondition); }
@Override public void visit( Join join ) { join.getLeft().accept(this); // if (join.getType() != JoinType.INNER) { sb.append(' ').append(join.type().symbol()); // } else { // sb.append(','); // } append(' '); join.getRight().accept(this); append(" ON "); join.getJoinCondition().accept(this); }
@Override public Join join( javax.jcr.query.qom.Source left, javax.jcr.query.qom.Source right, String joinType, javax.jcr.query.qom.JoinCondition joinCondition ) { Source leftSource = CheckArg.getInstanceOf(left, Source.class, "left"); Source rightSource = CheckArg.getInstanceOf(right, Source.class, "right"); JoinCondition jcrJoinCondition = CheckArg.getInstanceOf(joinCondition, JoinCondition.class, "joinCondition"); CheckArg.isNotEmpty(joinType, "joinType"); joinType = joinType.trim(); JoinType type = null; if (QueryObjectModelConstants.JCR_JOIN_TYPE_CROSS.equals(joinType)) type = JoinType.CROSS; else if (QueryObjectModelConstants.JCR_JOIN_TYPE_INNER.equals(joinType)) type = JoinType.INNER; else if (QueryObjectModelConstants.JCR_JOIN_TYPE_FULL_OUTER.equals(joinType)) type = JoinType.FULL_OUTER; else if (QueryObjectModelConstants.JCR_JOIN_TYPE_LEFT_OUTER.equals(joinType)) type = JoinType.LEFT_OUTER; else if (QueryObjectModelConstants.JCR_JOIN_TYPE_RIGHT_OUTER.equals(joinType)) type = JoinType.RIGHT_OUTER; if (type == null) { throw new IllegalArgumentException("Unknown or unsupported join type: " + joinType); } return new Join(leftSource, type, rightSource, jcrJoinCondition); }
@Override public void visit( Join join ) { join.getLeft().accept(this); // if (join.getType() != JoinType.INNER) { sb.append(' ').append(join.type().symbol()); // } else { // sb.append(','); // } append(' '); join.getRight().accept(this); append(" ON "); join.getJoinCondition().accept(this); }
if (usesSelector(next, selector1)) { Source right = joinableSources.getSelectors().get(selector2.name()); replacement = new Join(next, JoinType.INNER, right, joinCondition); } else if (usesSelector(next, selector2)) { Source left = joinableSources.getSelectors().get(selector1.name()); replacement = new Join(left, JoinType.INNER, next, joinCondition); throw new ParsingException(pos, msg); joins.add(new Join(left, JoinType.INNER, right, joinCondition));
@Test public void shouldParseDescendantNodeJoinWithNoCriteria() { query = parse("select * from [lom:Metadata] as lom join [lom:LangString] as lang on isdescendantnode(lang,lom)"); // SELECT * ... assertThat(query.columns().isEmpty(), is(true)); // FROM ... Join join = isJoin(query.source()); assertThat(join.getLeft(), is((Source)namedSelector(selectorName("lom:Metadata"), selectorName("lom")))); assertThat(join.getRight(), is((Source)namedSelector(selectorName("lom:LangString"), selectorName("lang")))); assertThat(join.type(), is(JoinType.INNER)); DescendantNodeJoinCondition joinCondition = isDescendantNodeJoinCondition(join.getJoinCondition()); assertThat(joinCondition.ancestorSelectorName(), is(selectorName("lom"))); assertThat(joinCondition.descendantSelectorName(), is(selectorName("lang"))); }
if (usesSelector(next, selector1)) { Source right = joinableSources.getSelectors().get(selector2.name()); replacement = new Join(next, JoinType.INNER, right, joinCondition); } else if (usesSelector(next, selector2)) { Source left = joinableSources.getSelectors().get(selector1.name()); replacement = new Join(left, JoinType.INNER, next, joinCondition); throw new ParsingException(pos, msg); joins.add(new Join(left, JoinType.INNER, right, joinCondition));
@Test public void shouldParseSelectStarFromTwoJoinedSourcesWithWhereContainingJoinCriteria() { query = parse("SELECT * FROM [mgnl:content] JOIN [acme:stuff] ON ISSAMENODE([mgnl:content],[acme:stuff])"); // SELECT * ... assertThat(query.columns().isEmpty(), is(true)); // FROM ... Join join = isJoin(query.source()); assertThat(join.getLeft(), is((Source)namedSelector(selectorName("mgnl:content")))); assertThat(join.getRight(), is((Source)namedSelector(selectorName("acme:stuff")))); assertThat(join.type(), is(JoinType.INNER)); SameNodeJoinCondition joinCondition = isSameNodeJoinCondition(join.getJoinCondition()); assertThat(joinCondition.selector1Name(), is(selectorName("mgnl:content"))); assertThat(joinCondition.selector2Name(), is(selectorName("acme:stuff"))); assertThat(joinCondition.getSelector2Path(), is(nullValue())); // WHERE ... assertThat(query.constraint(), is(nullValue())); }
@Test public void shouldParseSelectStarFromTwoJoinedSourcesWithWhereContainingJoinCriteria() { query = parse("SELECT * FROM mgnl:content, acme:stuff WHERE mgnl:content.jcr:path = acme:stuff.jcr:path"); // SELECT * ... assertThat(query.columns().isEmpty(), is(true)); // FROM ... Join join = isJoin(query.source()); assertThat(join.getLeft(), is((Source)namedSelector(selectorName("mgnl:content")))); assertThat(join.getRight(), is((Source)namedSelector(selectorName("acme:stuff")))); assertThat(join.type(), is(JoinType.INNER)); SameNodeJoinCondition joinCondition = isSameNodeJoinCondition(join.getJoinCondition()); assertThat(joinCondition.selector1Name(), is(selectorName("mgnl:content"))); assertThat(joinCondition.selector2Name(), is(selectorName("acme:stuff"))); assertThat(joinCondition.getSelector2Path(), is(nullValue())); // WHERE ... assertThat(query.constraint(), is(nullValue())); }
@Test public void shouldParseSelectStarFromThreeJoinedSourcesWithWhereContainingJoinCriteria() { query = parse("SELECT * FROM mgnl:content, acme:stuff, foo:bar WHERE mgnl:content.jcr:path = acme:stuff.jcr:path AND mgnl:content.jcr:path = foo:bar.jcr:path"); // SELECT * ... assertThat(query.columns().isEmpty(), is(true)); // FROM ... Join join = isJoin(query.source()); Join join2 = isJoin(join.getLeft()); assertThat(join2.getLeft(), is((Source)namedSelector(selectorName("mgnl:content")))); assertThat(join2.getRight(), is((Source)namedSelector(selectorName("acme:stuff")))); assertThat(join2.type(), is(JoinType.INNER)); SameNodeJoinCondition joinCondition2 = isSameNodeJoinCondition(join2.getJoinCondition()); assertThat(joinCondition2.selector1Name(), is(selectorName("mgnl:content"))); assertThat(joinCondition2.selector2Name(), is(selectorName("acme:stuff"))); assertThat(joinCondition2.getSelector2Path(), is(nullValue())); assertThat(join.getRight(), is((Source)namedSelector(selectorName("foo:bar")))); assertThat(join.type(), is(JoinType.INNER)); SameNodeJoinCondition joinCondition = isSameNodeJoinCondition(join.getJoinCondition()); assertThat(joinCondition.selector1Name(), is(selectorName("mgnl:content"))); assertThat(joinCondition.selector2Name(), is(selectorName("foo:bar"))); assertThat(joinCondition.getSelector2Path(), is(nullValue())); // WHERE ... assertThat(query.constraint(), is(nullValue())); }