use of org.hibernate.query.sqm.tree.SqmJoinType 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.SqmJoinType in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method consumeAttributeJoin.
private TableGroup consumeAttributeJoin(SqmAttributeJoin<?, ?> sqmJoin, TableGroup lhsTableGroup, TableGroup ownerTableGroup, boolean transitive) {
final SqmPathSource<?> pathSource = sqmJoin.getReferencedPathSource();
final SqmJoinType sqmJoinType = sqmJoin.getSqmJoinType();
final TableGroupJoin joinedTableGroupJoin;
final TableGroup joinedTableGroup;
final NavigablePath sqmJoinNavigablePath = sqmJoin.getNavigablePath();
final ModelPart modelPart = ownerTableGroup.getModelPart().findSubPart(pathSource.getPathName(), SqmMappingModelHelper.resolveExplicitTreatTarget(sqmJoin, this));
if (pathSource instanceof PluralPersistentAttribute) {
assert modelPart instanceof PluralAttributeMapping;
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) modelPart;
if (sqmJoin.isFetched()) {
containsCollectionFetches = true;
}
joinedTableGroupJoin = pluralAttributeMapping.createTableGroupJoin(sqmJoinNavigablePath, ownerTableGroup, sqmJoin.getExplicitAlias(), sqmJoinType.getCorrespondingSqlJoinType(), sqmJoin.isFetched(), sqmJoin.getJoinPredicate() != null, this);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
pluralAttributeMapping.applyBaseRestrictions((predicate) -> {
final PredicateCollector existing = collectionFilterPredicates.get(joinedTableGroup.getGroupAlias());
final PredicateCollector collector;
if (existing == null) {
collector = new PredicateCollector(predicate);
collectionFilterPredicates.put(joinedTableGroup.getGroupAlias(), collector);
} else {
collector = existing;
collector.applyPredicate(predicate);
}
}, joinedTableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
} else {
assert modelPart instanceof TableGroupJoinProducer;
joinedTableGroupJoin = ((TableGroupJoinProducer) modelPart).createTableGroupJoin(sqmJoinNavigablePath, ownerTableGroup, sqmJoin.getExplicitAlias(), sqmJoinType.getCorrespondingSqlJoinType(), sqmJoin.isFetched(), sqmJoin.getJoinPredicate() != null, this);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
// Left or inner singular attribute joins without a predicate can be safely optimized away
if (sqmJoin.getJoinPredicate() != null || sqmJoinType != SqmJoinType.INNER && sqmJoinType != SqmJoinType.LEFT) {
joinedTableGroup.getPrimaryTableReference();
}
}
lhsTableGroup.addTableGroupJoin(joinedTableGroupJoin);
getFromClauseIndex().register(sqmJoin, joinedTableGroup);
registerPluralTableGroupParts(joinedTableGroup);
// For joins we also need to register the table groups for the treats
if (joinedTableGroup instanceof PluralTableGroup) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) joinedTableGroup;
for (SqmFrom<?, ?> sqmTreat : sqmJoin.getSqmTreats()) {
if (pluralTableGroup.getElementTableGroup() != null) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath().append(CollectionPart.Nature.ELEMENT.getName()), pluralTableGroup.getElementTableGroup());
}
if (pluralTableGroup.getIndexTableGroup() != null) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath().append(CollectionPart.Nature.INDEX.getName()), pluralTableGroup.getIndexTableGroup());
}
}
} else {
for (SqmFrom<?, ?> sqmTreat : sqmJoin.getSqmTreats()) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath(), joinedTableGroup);
}
}
// add any additional join restrictions
if (sqmJoin.getJoinPredicate() != null) {
if (sqmJoin.isFetched()) {
QueryLogging.QUERY_MESSAGE_LOGGER.debugf("Join fetch [" + sqmJoinNavigablePath + "] is restricted");
}
final SqmJoin<?, ?> oldJoin = currentlyProcessingJoin;
currentlyProcessingJoin = sqmJoin;
joinedTableGroupJoin.applyPredicate(visitNestedTopLevelPredicate(sqmJoin.getJoinPredicate()));
currentlyProcessingJoin = oldJoin;
}
if (transitive) {
consumeExplicitJoins(sqmJoin, joinedTableGroup);
}
return joinedTableGroup;
}
Aggregations