use of org.hibernate.query.sqm.tree.from.SqmAttributeJoin in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method consumeJoin.
protected <X> void consumeJoin(HqlParser.JoinContext parserJoin, SqmRoot<X> sqmRoot) {
final SqmJoinType joinType;
final int firstJoinTypeSymbolType;
if (parserJoin.getChild(0) instanceof HqlParser.JoinTypeContext && parserJoin.getChild(0).getChildCount() != 0) {
firstJoinTypeSymbolType = ((TerminalNode) parserJoin.getChild(0).getChild(0)).getSymbol().getType();
} else {
firstJoinTypeSymbolType = HqlParser.INNER;
}
switch(firstJoinTypeSymbolType) {
case HqlParser.FULL:
joinType = SqmJoinType.FULL;
break;
case HqlParser.RIGHT:
joinType = SqmJoinType.RIGHT;
break;
// For some reason, we also support `outer join` syntax..
case HqlParser.OUTER:
case HqlParser.LEFT:
joinType = SqmJoinType.LEFT;
break;
default:
joinType = SqmJoinType.INNER;
break;
}
final HqlParser.JoinPathContext qualifiedJoinPathContext = parserJoin.joinPath();
final HqlParser.VariableContext identificationVariableDefContext;
if (qualifiedJoinPathContext.getChildCount() > 1) {
identificationVariableDefContext = (HqlParser.VariableContext) qualifiedJoinPathContext.getChild(1);
} else {
identificationVariableDefContext = null;
}
final String alias = visitVariable(identificationVariableDefContext);
final boolean fetch = parserJoin.getChild(2) instanceof TerminalNode;
if (fetch && processingStateStack.depth() > 1) {
throw new SemanticException("fetch not allowed in subquery from-elements");
}
dotIdentifierConsumerStack.push(new QualifiedJoinPathConsumer(sqmRoot, joinType, fetch, alias, this));
try {
// noinspection unchecked
final SqmQualifiedJoin<X, ?> join = (SqmQualifiedJoin<X, ?>) qualifiedJoinPathContext.getChild(0).accept(this);
final HqlParser.JoinRestrictionContext qualifiedJoinRestrictionContext = parserJoin.joinRestriction();
if (join instanceof SqmEntityJoin<?>) {
sqmRoot.addSqmJoin(join);
} else if (join instanceof SqmAttributeJoin<?, ?>) {
final SqmAttributeJoin<?, ?> attributeJoin = (SqmAttributeJoin<?, ?>) join;
if (getCreationOptions().useStrictJpaCompliance()) {
if (join.getExplicitAlias() != null) {
if (attributeJoin.isFetched()) {
throw new StrictJpaComplianceViolation("Encountered aliased fetch join, but strict JPQL compliance was requested", StrictJpaComplianceViolation.Type.ALIASED_FETCH_JOIN);
}
}
}
if (qualifiedJoinRestrictionContext != null && attributeJoin.isFetched()) {
throw new SemanticException("with-clause not allowed on fetched associations; use filters");
}
}
if (qualifiedJoinRestrictionContext != null) {
dotIdentifierConsumerStack.push(new QualifiedJoinPredicatePathConsumer(join, this));
try {
join.setJoinPredicate((SqmPredicate) qualifiedJoinRestrictionContext.getChild(1).accept(this));
} finally {
dotIdentifierConsumerStack.pop();
}
}
} finally {
dotIdentifierConsumerStack.pop();
}
}
use of org.hibernate.query.sqm.tree.from.SqmAttributeJoin in project hibernate-orm by hibernate.
the class AbstractSqmFrom method resolvePathPart.
@Override
public SqmPath<?> resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {
// Try to resolve an existing attribute join without ON clause
SqmPath<?> resolvedPath = null;
ModelPartContainer modelPartContainer = null;
for (SqmJoin<?, ?> sqmJoin : getSqmJoins()) {
// We can only match singular joins here, as plural path parts are interpreted like sub-queries
if (sqmJoin instanceof SqmSingularJoin<?, ?> && name.equals(sqmJoin.getReferencedPathSource().getPathName())) {
final SqmAttributeJoin<?, ?> attributeJoin = (SqmAttributeJoin<?, ?>) sqmJoin;
if (attributeJoin.getOn() == null) {
// todo (6.0): to match the expectation of the JPA spec I think we also have to check
// that the join type is INNER or the default join type for the attribute,
// but as far as I understand, in 5.x we expect to ignore this behavior
// if ( attributeJoin.getSqmJoinType() != SqmJoinType.INNER ) {
// if ( attributeJoin.getAttribute().isCollection() ) {
// continue;
// }
// if ( modelPartContainer == null ) {
// modelPartContainer = findModelPartContainer( attributeJoin, creationState );
// }
// final TableGroupJoinProducer joinProducer = (TableGroupJoinProducer) modelPartContainer.findSubPart(
// name,
// null
// );
// if ( attributeJoin.getSqmJoinType().getCorrespondingSqlJoinType() != joinProducer.getDefaultSqlAstJoinType( null ) ) {
// continue;
// }
// }
resolvedPath = sqmJoin;
if (attributeJoin.isFetched()) {
break;
}
}
}
}
if (resolvedPath != null) {
return resolvedPath;
}
final SqmPath<?> sqmPath = get(name);
creationState.getProcessingStateStack().getCurrent().getPathRegistry().register(sqmPath);
return sqmPath;
}
Aggregations