Search in sources :

Example 1 with SqmSubQuery

use of org.hibernate.query.sqm.tree.select.SqmSubQuery in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitSubquery.

@Override
public SqmSubQuery<?> visitSubquery(HqlParser.SubqueryContext ctx) {
    final HqlParser.QueryExpressionContext queryExpressionContext = (HqlParser.QueryExpressionContext) ctx.getChild(0);
    final SqmSubQuery<?> subQuery = new SqmSubQuery<>(processingStateStack.getCurrent().getProcessingQuery(), creationContext.getNodeBuilder());
    processingStateStack.push(new SqmQuerySpecCreationProcessingStateStandardImpl(processingStateStack.getCurrent(), subQuery, this));
    try {
        queryExpressionContext.accept(this);
        final List<SqmSelection<?>> selections = subQuery.getQuerySpec().getSelectClause().getSelections();
        if (selections.size() == 1) {
            subQuery.applyInferableType(selections.get(0).getNodeType());
        }
        return subQuery;
    } finally {
        processingStateStack.pop();
    }
}
Also used : SqmSubQuery(org.hibernate.query.sqm.tree.select.SqmSubQuery) SqmSelection(org.hibernate.query.sqm.tree.select.SqmSelection) HqlParser(org.hibernate.grammars.hql.HqlParser) SqmQuerySpecCreationProcessingStateStandardImpl(org.hibernate.query.sqm.internal.SqmQuerySpecCreationProcessingStateStandardImpl)

Example 2 with SqmSubQuery

use of org.hibernate.query.sqm.tree.select.SqmSubQuery in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitAnyFunction.

@Override
public SqmExpression<?> visitAnyFunction(HqlParser.AnyFunctionContext ctx) {
    final SqmPredicate filterExpression = getFilterExpression(ctx);
    final ParseTree argumentChild = ctx.getChild(2);
    if (argumentChild instanceof HqlParser.SubqueryContext) {
        final SqmSubQuery<?> subquery = (SqmSubQuery<?>) argumentChild.accept(this);
        return new SqmAny<>(subquery, creationContext.getNodeBuilder());
    } else if (argumentChild instanceof HqlParser.PredicateContext) {
        if (getCreationOptions().useStrictJpaCompliance()) {
            throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.FUNCTION_CALL);
        }
        final SqmExpression<?> argument = (SqmExpression<?>) argumentChild.accept(this);
        return applyOverClause(ctx, getFunctionDescriptor("any").generateAggregateSqmExpression(singletonList(argument), filterExpression, resolveExpressibleTypeBasic(Boolean.class), creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration()));
    } else {
        if (getCreationOptions().useStrictJpaCompliance()) {
            throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.HQL_COLLECTION_FUNCTION);
        }
        return new SqmAny<>(createCollectionReferenceSubQuery((HqlParser.SimplePathContext) ctx.getChild(3), (TerminalNode) ctx.getChild(1)), creationContext.getNodeBuilder());
    }
}
Also used : SqmAny(org.hibernate.query.sqm.tree.expression.SqmAny) SqmPredicate(org.hibernate.query.sqm.tree.predicate.SqmPredicate) SqmSubQuery(org.hibernate.query.sqm.tree.select.SqmSubQuery) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) HqlParser(org.hibernate.grammars.hql.HqlParser) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Example 3 with SqmSubQuery

use of org.hibernate.query.sqm.tree.select.SqmSubQuery in project hibernate-orm by hibernate.

the class QualifiedJoinPredicatePathConsumer method createBasePart.

@Override
protected SemanticPathPart createBasePart() {
    return new BaseLocalSequencePart() {

        @Override
        protected void validateAsRoot(SqmFrom<?, ?> pathRoot) {
            final SqmRoot<?> root = pathRoot.findRoot();
            final SqmRoot<?> joinRoot = sqmJoin.findRoot();
            if (root != joinRoot) {
                // The root of a path within a join condition doesn't have the same root as the current join we are processing.
                // The aim of this check is to prevent uses of different "spaces" i.e. `from A a, B b join b.id = a.id` would be illegal
                SqmCreationProcessingState processingState = getCreationState().getCurrentProcessingState();
                // First, we need to find out if the current join is part of current processing query
                final SqmQuery<?> currentProcessingQuery = processingState.getProcessingQuery();
                if (currentProcessingQuery instanceof SqmSelectQuery<?>) {
                    final SqmQuerySpec<?> querySpec = ((SqmSelectQuery<?>) currentProcessingQuery).getQuerySpec();
                    final SqmFromClause fromClause = querySpec.getFromClause();
                    // then the root of the processing path must be a root of one of the parent queries
                    if (fromClause != null && fromClause.getRoots().contains(joinRoot)) {
                        // It is allowed to use correlations from the same query
                        if (!(root instanceof SqmCorrelation<?, ?>) || !fromClause.getRoots().contains(root)) {
                            validateAsRootOnParentQueryClosure(pathRoot, root, processingState.getParentProcessingState());
                        }
                        return;
                    }
                }
                // in which case the path root is allowed to occur in the current processing query as root
                if (currentProcessingQuery instanceof SqmSubQuery<?>) {
                    validateAsRootOnParentQueryClosure(pathRoot, root, processingState);
                    return;
                }
                throw new SemanticException(String.format(Locale.ROOT, "SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]", pathRoot.getNavigablePath().getFullPath(), sqmJoin.getNavigablePath().getFullPath()));
            }
            super.validateAsRoot(pathRoot);
        }

        private void validateAsRootOnParentQueryClosure(SqmFrom<?, ?> pathRoot, SqmRoot<?> root, SqmCreationProcessingState processingState) {
            while (processingState != null) {
                final SqmQuery<?> processingQuery = processingState.getProcessingQuery();
                if (processingQuery instanceof SqmSelectQuery<?>) {
                    final SqmQuerySpec<?> querySpec = ((SqmSelectQuery<?>) processingQuery).getQuerySpec();
                    final SqmFromClause fromClause = querySpec.getFromClause();
                    // i.e. `from A a, B b join b.id = a.id` would be illegal
                    if (fromClause != null && fromClause.getRoots().contains(root)) {
                        super.validateAsRoot(pathRoot);
                        return;
                    }
                }
                processingState = processingState.getParentProcessingState();
            }
            throw new SemanticException(String.format(Locale.ROOT, "SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]", pathRoot.getNavigablePath().getFullPath(), sqmJoin.getNavigablePath().getFullPath()));
        }
    };
}
Also used : SqmSelectQuery(org.hibernate.query.sqm.tree.select.SqmSelectQuery) SqmSubQuery(org.hibernate.query.sqm.tree.select.SqmSubQuery) SqmFrom(org.hibernate.query.sqm.tree.from.SqmFrom) SqmCreationProcessingState(org.hibernate.query.hql.spi.SqmCreationProcessingState) SqmFromClause(org.hibernate.query.sqm.tree.from.SqmFromClause) SqmRoot(org.hibernate.query.sqm.tree.from.SqmRoot) SemanticException(org.hibernate.query.SemanticException)

Example 4 with SqmSubQuery

use of org.hibernate.query.sqm.tree.select.SqmSubQuery in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitEveryFunction.

@Override
public SqmExpression<?> visitEveryFunction(HqlParser.EveryFunctionContext ctx) {
    final SqmPredicate filterExpression = getFilterExpression(ctx);
    final ParseTree argumentChild = ctx.getChild(2);
    if (argumentChild instanceof HqlParser.SubqueryContext) {
        final SqmSubQuery<?> subquery = (SqmSubQuery<?>) argumentChild.accept(this);
        return new SqmEvery<>(subquery, creationContext.getNodeBuilder());
    } else if (argumentChild instanceof HqlParser.PredicateContext) {
        if (getCreationOptions().useStrictJpaCompliance()) {
            throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.FUNCTION_CALL);
        }
        final SqmExpression<?> argument = (SqmExpression<?>) argumentChild.accept(this);
        return applyOverClause(ctx, getFunctionDescriptor("every").generateAggregateSqmExpression(singletonList(argument), filterExpression, resolveExpressibleTypeBasic(Boolean.class), creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration()));
    } else {
        if (getCreationOptions().useStrictJpaCompliance()) {
            throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.HQL_COLLECTION_FUNCTION);
        }
        return new SqmEvery<>(createCollectionReferenceSubQuery((HqlParser.SimplePathContext) ctx.getChild(3), (TerminalNode) ctx.getChild(1)), creationContext.getNodeBuilder());
    }
}
Also used : SqmPredicate(org.hibernate.query.sqm.tree.predicate.SqmPredicate) SqmSubQuery(org.hibernate.query.sqm.tree.select.SqmSubQuery) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) HqlParser(org.hibernate.grammars.hql.HqlParser) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) SqmEvery(org.hibernate.query.sqm.tree.expression.SqmEvery) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Example 5 with SqmSubQuery

use of org.hibernate.query.sqm.tree.select.SqmSubQuery 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

SqmSubQuery (org.hibernate.query.sqm.tree.select.SqmSubQuery)7 HqlParser (org.hibernate.grammars.hql.HqlParser)3 SqmExpression (org.hibernate.query.sqm.tree.expression.SqmExpression)3 ParseTree (org.antlr.v4.runtime.tree.ParseTree)2 SemanticException (org.hibernate.query.SemanticException)2 SqmCreationProcessingState (org.hibernate.query.hql.spi.SqmCreationProcessingState)2 StrictJpaComplianceViolation (org.hibernate.query.sqm.StrictJpaComplianceViolation)2 SqmLiteral (org.hibernate.query.sqm.tree.expression.SqmLiteral)2 SqmFromClause (org.hibernate.query.sqm.tree.from.SqmFromClause)2 SqmPredicate (org.hibernate.query.sqm.tree.predicate.SqmPredicate)2 SqmSelectClause (org.hibernate.query.sqm.tree.select.SqmSelectClause)2 SqmSelection (org.hibernate.query.sqm.tree.select.SqmSelection)2 Root (jakarta.persistence.criteria.Root)1 BigInteger (java.math.BigInteger)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 HibernateException (org.hibernate.HibernateException)1 NotYetImplementedFor6Exception (org.hibernate.NotYetImplementedFor6Exception)1 QueryException (org.hibernate.QueryException)1 MultipleBagFetchException (org.hibernate.loader.MultipleBagFetchException)1