Search in sources :

Example 1 with SqmJoinType

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();
    }
}
Also used : SqmQualifiedJoin(org.hibernate.query.sqm.tree.from.SqmQualifiedJoin) SqmEntityJoin(org.hibernate.query.sqm.tree.from.SqmEntityJoin) SqmJoinType(org.hibernate.query.sqm.tree.SqmJoinType) HqlParser(org.hibernate.grammars.hql.HqlParser) SqmAttributeJoin(org.hibernate.query.sqm.tree.from.SqmAttributeJoin) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) SemanticException(org.hibernate.query.SemanticException)

Example 2 with SqmJoinType

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;
}
Also used : VirtualTableGroup(org.hibernate.sql.ast.tree.from.VirtualTableGroup) LazyTableGroup(org.hibernate.sql.ast.tree.from.LazyTableGroup) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) CorrelatedTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedTableGroup) CorrelatedPluralTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup) PluralTableGroup(org.hibernate.sql.ast.tree.from.PluralTableGroup) QueryPartTableGroup(org.hibernate.sql.ast.tree.from.QueryPartTableGroup) NavigablePath(org.hibernate.query.spi.NavigablePath) TableGroupJoinProducer(org.hibernate.sql.ast.tree.from.TableGroupJoinProducer) ConvertibleModelPart(org.hibernate.metamodel.mapping.ConvertibleModelPart) ModelPart(org.hibernate.metamodel.mapping.ModelPart) EntityValuedModelPart(org.hibernate.metamodel.mapping.EntityValuedModelPart) BasicValuedModelPart(org.hibernate.metamodel.mapping.BasicValuedModelPart) EmbeddableValuedModelPart(org.hibernate.metamodel.mapping.EmbeddableValuedModelPart) PluralPersistentAttribute(org.hibernate.metamodel.model.domain.PluralPersistentAttribute) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) CorrelatedPluralTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup) PluralTableGroup(org.hibernate.sql.ast.tree.from.PluralTableGroup) TableGroupJoin(org.hibernate.sql.ast.tree.from.TableGroupJoin) SqmJoinType(org.hibernate.query.sqm.tree.SqmJoinType) PredicateCollector(org.hibernate.sql.ast.tree.predicate.PredicateCollector)

Aggregations

SqmJoinType (org.hibernate.query.sqm.tree.SqmJoinType)2 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)1 HqlParser (org.hibernate.grammars.hql.HqlParser)1 BasicValuedModelPart (org.hibernate.metamodel.mapping.BasicValuedModelPart)1 ConvertibleModelPart (org.hibernate.metamodel.mapping.ConvertibleModelPart)1 EmbeddableValuedModelPart (org.hibernate.metamodel.mapping.EmbeddableValuedModelPart)1 EntityValuedModelPart (org.hibernate.metamodel.mapping.EntityValuedModelPart)1 ModelPart (org.hibernate.metamodel.mapping.ModelPart)1 PluralAttributeMapping (org.hibernate.metamodel.mapping.PluralAttributeMapping)1 PluralPersistentAttribute (org.hibernate.metamodel.model.domain.PluralPersistentAttribute)1 SemanticException (org.hibernate.query.SemanticException)1 NavigablePath (org.hibernate.query.spi.NavigablePath)1 StrictJpaComplianceViolation (org.hibernate.query.sqm.StrictJpaComplianceViolation)1 SqmAttributeJoin (org.hibernate.query.sqm.tree.from.SqmAttributeJoin)1 SqmEntityJoin (org.hibernate.query.sqm.tree.from.SqmEntityJoin)1 SqmQualifiedJoin (org.hibernate.query.sqm.tree.from.SqmQualifiedJoin)1 CorrelatedPluralTableGroup (org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup)1 CorrelatedTableGroup (org.hibernate.sql.ast.tree.from.CorrelatedTableGroup)1 LazyTableGroup (org.hibernate.sql.ast.tree.from.LazyTableGroup)1 PluralTableGroup (org.hibernate.sql.ast.tree.from.PluralTableGroup)1