Search in sources :

Example 1 with AbstractSqmFrom

use of org.hibernate.query.sqm.tree.domain.AbstractSqmFrom in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method createCollectionReferenceSubQuery.

private <X> SqmSubQuery<X> createCollectionReferenceSubQuery(HqlParser.SimplePathContext pathCtx, TerminalNode collectionReferenceCtx) {
    final SqmPath<?> pluralAttributePath = consumeDomainPath(pathCtx);
    final SqmPathSource<?> referencedPathSource = pluralAttributePath.getReferencedPathSource();
    if (!(referencedPathSource instanceof PluralPersistentAttribute)) {
        throw new PathException("Path is not a plural path '" + pluralAttributePath.getNavigablePath() + "'");
    }
    final SqmSubQuery<?> subQuery = new SqmSubQuery<>(processingStateStack.getCurrent().getProcessingQuery(), creationContext.getNodeBuilder());
    final SqmSelectClause selectClause = new SqmSelectClause(false, 1, creationContext.getNodeBuilder());
    final SqmFromClause fromClause = new SqmFromClause(1);
    SqmPath<?> lhs = pluralAttributePath.getLhs();
    final List<String> implicitJoinPaths = new ArrayList<>();
    while (!(lhs instanceof AbstractSqmFrom<?, ?>)) {
        implicitJoinPaths.add(lhs.getNavigablePath().getUnaliasedLocalName());
        lhs = lhs.getLhs();
    }
    final AbstractSqmFrom<?, ?> correlationBase = (AbstractSqmFrom<?, ?>) lhs;
    final SqmCorrelation<?, ?> correlation = correlationBase.createCorrelation();
    SqmFrom<?, ?> joinBase = correlation;
    for (int i = implicitJoinPaths.size() - 1; i >= 0; i--) {
        joinBase = joinBase.join(implicitJoinPaths.get(i));
    }
    final SqmAttributeJoin<?, ?> collectionJoin = joinBase.join(pluralAttributePath.getNavigablePath().getUnaliasedLocalName());
    fromClause.addRoot(correlation.getCorrelatedRoot());
    if (collectionReferenceCtx == null) {
        final SqmLiteral<Integer> literal = new SqmLiteral<>(1, creationContext.getNodeBuilder().getIntegerType(), creationContext.getNodeBuilder());
        subQuery.applyInferableType(literal.getNodeType());
        selectClause.setSelection(literal);
    } else {
        final String partName;
        switch(collectionReferenceCtx.getSymbol().getType()) {
            case HqlParser.ELEMENTS:
                partName = CollectionPart.Nature.ELEMENT.getName();
                break;
            case HqlParser.INDICES:
                partName = CollectionPart.Nature.INDEX.getName();
                break;
            default:
                throw new ParsingException("Unexpected collection reference : " + collectionReferenceCtx.getText());
        }
        final SqmPath<?> path = collectionJoin.resolvePathPart(partName, true, this);
        subQuery.applyInferableType(path.getNodeType());
        selectClause.setSelection(path);
    }
    final SqmQuerySpec<?> querySpec = subQuery.getQuerySpec();
    querySpec.setFromClause(fromClause);
    querySpec.setSelectClause(selectClause);
    // noinspection unchecked
    return (SqmSubQuery<X>) subQuery;
}
Also used : SqmSubQuery(org.hibernate.query.sqm.tree.select.SqmSubQuery) PluralPersistentAttribute(org.hibernate.metamodel.model.domain.PluralPersistentAttribute) SqmSelectClause(org.hibernate.query.sqm.tree.select.SqmSelectClause) ArrayList(java.util.ArrayList) AbstractSqmFrom(org.hibernate.query.sqm.tree.domain.AbstractSqmFrom) PathException(org.hibernate.query.PathException) BigInteger(java.math.BigInteger) ParsingException(org.hibernate.query.sqm.ParsingException) SqmFromClause(org.hibernate.query.sqm.tree.from.SqmFromClause) SqmLiteral(org.hibernate.query.sqm.tree.expression.SqmLiteral)

Aggregations

BigInteger (java.math.BigInteger)1 ArrayList (java.util.ArrayList)1 PluralPersistentAttribute (org.hibernate.metamodel.model.domain.PluralPersistentAttribute)1 PathException (org.hibernate.query.PathException)1 ParsingException (org.hibernate.query.sqm.ParsingException)1 AbstractSqmFrom (org.hibernate.query.sqm.tree.domain.AbstractSqmFrom)1 SqmLiteral (org.hibernate.query.sqm.tree.expression.SqmLiteral)1 SqmFromClause (org.hibernate.query.sqm.tree.from.SqmFromClause)1 SqmSelectClause (org.hibernate.query.sqm.tree.select.SqmSelectClause)1 SqmSubQuery (org.hibernate.query.sqm.tree.select.SqmSubQuery)1