Search in sources :

Example 1 with SqmCreationProcessingState

use of org.hibernate.query.hql.spi.SqmCreationProcessingState in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitSetQueryGroup.

@Override
public SqmQueryGroup<Object> visitSetQueryGroup(HqlParser.SetQueryGroupContext ctx) {
    if (creationOptions.useStrictJpaCompliance()) {
        throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.SET_OPERATIONS);
    }
    final List<ParseTree> children = ctx.children;
    // noinspection unchecked
    final SqmQueryPart<Object> firstQueryPart = (SqmQueryPart<Object>) children.get(0).accept(this);
    SqmQueryGroup<Object> queryGroup;
    if (firstQueryPart instanceof SqmQueryGroup<?>) {
        queryGroup = (SqmQueryGroup<Object>) firstQueryPart;
    } else {
        queryGroup = new SqmQueryGroup<>(firstQueryPart);
    }
    setCurrentQueryPart(queryGroup);
    final int size = children.size();
    final SqmCreationProcessingState firstProcessingState = processingStateStack.pop();
    for (int i = 1; i < size; i += 2) {
        final SetOperator operator = visitSetOperator((HqlParser.SetOperatorContext) children.get(i));
        final HqlParser.OrderedQueryContext simpleQueryCtx = (HqlParser.OrderedQueryContext) children.get(i + 1);
        final List<SqmQueryPart<Object>> queryParts;
        if (queryGroup.getSetOperator() == null || queryGroup.getSetOperator() == operator) {
            queryGroup.setSetOperator(operator);
            queryParts = queryGroup.queryParts();
        } else {
            queryParts = new ArrayList<>(size - (i >> 1));
            queryParts.add(queryGroup);
            queryGroup = new SqmQueryGroup<>(creationContext.getNodeBuilder(), operator, queryParts);
            setCurrentQueryPart(queryGroup);
        }
        final SqmQueryPart<Object> queryPart;
        try {
            processingStateStack.push(new SqmQuerySpecCreationProcessingStateStandardImpl(processingStateStack.getCurrent(), (SqmSelectQuery<?>) firstProcessingState.getProcessingQuery(), this));
            final List<ParseTree> subChildren = simpleQueryCtx.children;
            if (subChildren.get(0) instanceof HqlParser.QueryContext) {
                final SqmQuerySpec<Object> querySpec = new SqmQuerySpec<>(creationContext.getNodeBuilder());
                queryParts.add(querySpec);
                visitQuerySpecExpression((HqlParser.QuerySpecExpressionContext) simpleQueryCtx);
            } else {
                try {
                    final SqmSelectStatement<Object> selectStatement = new SqmSelectStatement<>(creationContext.getNodeBuilder());
                    processingStateStack.push(new SqmQuerySpecCreationProcessingStateStandardImpl(processingStateStack.getCurrent(), selectStatement, this));
                    queryPart = visitNestedQueryExpression((HqlParser.NestedQueryExpressionContext) simpleQueryCtx);
                    queryParts.add(queryPart);
                } finally {
                    processingStateStack.pop();
                }
            }
        } finally {
            processingStateStack.pop();
        }
    }
    processingStateStack.push(firstProcessingState);
    return queryGroup;
}
Also used : SqmCreationProcessingState(org.hibernate.query.hql.spi.SqmCreationProcessingState) SqmQueryGroup(org.hibernate.query.sqm.tree.select.SqmQueryGroup) SqmQuerySpecCreationProcessingStateStandardImpl(org.hibernate.query.sqm.internal.SqmQuerySpecCreationProcessingStateStandardImpl) SetOperator(org.hibernate.query.sqm.SetOperator) SqmSelectQuery(org.hibernate.query.sqm.tree.select.SqmSelectQuery) AbstractSqmSelectQuery(org.hibernate.query.sqm.tree.select.AbstractSqmSelectQuery) SqmSelectStatement(org.hibernate.query.sqm.tree.select.SqmSelectStatement) SqmQueryPart(org.hibernate.query.sqm.tree.select.SqmQueryPart) HqlParser(org.hibernate.grammars.hql.HqlParser) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) SqmQuerySpec(org.hibernate.query.sqm.tree.select.SqmQuerySpec) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Example 2 with SqmCreationProcessingState

use of org.hibernate.query.hql.spi.SqmCreationProcessingState in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitInsertStatement.

@Override
public SqmInsertStatement<R> visitInsertStatement(HqlParser.InsertStatementContext ctx) {
    final int dmlTargetIndex;
    if (ctx.getChild(1) instanceof HqlParser.TargetEntityContext) {
        dmlTargetIndex = 1;
    } else {
        dmlTargetIndex = 2;
    }
    final HqlParser.TargetEntityContext dmlTargetContext = (HqlParser.TargetEntityContext) ctx.getChild(dmlTargetIndex);
    final HqlParser.TargetFieldsContext targetFieldsSpecContext = (HqlParser.TargetFieldsContext) ctx.getChild(dmlTargetIndex + 1);
    final SqmRoot<R> root = visitTargetEntity(dmlTargetContext);
    if (root.getReferencedPathSource() instanceof SqmPolymorphicRootDescriptor<?>) {
        throw new SemanticException(String.format("Target type '%s' in insert statement is not an entity", root.getReferencedPathSource().getHibernateEntityName()));
    }
    final HqlParser.QueryExpressionContext queryExpressionContext = ctx.queryExpression();
    if (queryExpressionContext != null) {
        final SqmInsertSelectStatement<R> insertStatement = new SqmInsertSelectStatement<>(root, creationContext.getNodeBuilder());
        parameterCollector = insertStatement;
        final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(insertStatement, this);
        processingStateStack.push(processingState);
        try {
            queryExpressionContext.accept(this);
            final SqmCreationProcessingState stateFieldsProcessingState = new SqmCreationProcessingStateImpl(insertStatement, this);
            stateFieldsProcessingState.getPathRegistry().register(root);
            processingStateStack.push(stateFieldsProcessingState);
            try {
                for (HqlParser.SimplePathContext stateFieldCtx : targetFieldsSpecContext.simplePath()) {
                    final SqmPath<?> stateField = (SqmPath<?>) visitSimplePath(stateFieldCtx);
                    // todo : validate each resolved stateField...
                    insertStatement.addInsertTargetStateField(stateField);
                }
            } finally {
                processingStateStack.pop();
            }
            return insertStatement;
        } finally {
            processingStateStack.pop();
        }
    } else {
        final SqmInsertValuesStatement<R> insertStatement = new SqmInsertValuesStatement<>(root, creationContext.getNodeBuilder());
        parameterCollector = insertStatement;
        final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(insertStatement, this);
        processingStateStack.push(processingState);
        processingState.getPathRegistry().register(root);
        try {
            final HqlParser.ValuesListContext valuesListContext = ctx.valuesList();
            for (int i = 1; i < valuesListContext.getChildCount(); i += 2) {
                final ParseTree values = valuesListContext.getChild(i);
                final SqmValues sqmValues = new SqmValues();
                for (int j = 1; j < values.getChildCount(); j += 2) {
                    sqmValues.getExpressions().add((SqmExpression<?>) values.getChild(j).accept(this));
                }
                insertStatement.getValuesList().add(sqmValues);
            }
            for (HqlParser.SimplePathContext stateFieldCtx : targetFieldsSpecContext.simplePath()) {
                final SqmPath<?> stateField = (SqmPath<?>) visitSimplePath(stateFieldCtx);
                // todo : validate each resolved stateField...
                insertStatement.addInsertTargetStateField(stateField);
            }
            return insertStatement;
        } finally {
            processingStateStack.pop();
        }
    }
}
Also used : SqmInsertValuesStatement(org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement) SqmPath(org.hibernate.query.sqm.tree.domain.SqmPath) TIMEZONE_HOUR(org.hibernate.query.sqm.TemporalUnit.TIMEZONE_HOUR) WEEK_OF_YEAR(org.hibernate.query.sqm.TemporalUnit.WEEK_OF_YEAR) DAY_OF_YEAR(org.hibernate.query.sqm.TemporalUnit.DAY_OF_YEAR) IDENTIFIER(org.hibernate.grammars.hql.HqlParser.IDENTIFIER) SqmCreationProcessingState(org.hibernate.query.hql.spi.SqmCreationProcessingState) HqlParser(org.hibernate.grammars.hql.HqlParser) SqmValues(org.hibernate.query.sqm.tree.insert.SqmValues) SqmPolymorphicRootDescriptor(org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor) SqmInsertSelectStatement(org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement) SqmDmlCreationProcessingState(org.hibernate.query.sqm.internal.SqmDmlCreationProcessingState) SqmCreationProcessingStateImpl(org.hibernate.query.sqm.internal.SqmCreationProcessingStateImpl) ParseTree(org.antlr.v4.runtime.tree.ParseTree) SemanticException(org.hibernate.query.SemanticException)

Example 3 with SqmCreationProcessingState

use of org.hibernate.query.hql.spi.SqmCreationProcessingState in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitRootEntity.

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public SqmRoot<?> visitRootEntity(HqlParser.RootEntityContext ctx) {
    final HqlParser.EntityNameContext entityNameContext = (HqlParser.EntityNameContext) ctx.getChild(0);
    final List<ParseTree> entityNameParseTreeChildren = entityNameContext.children;
    final String name = getEntityName(entityNameContext);
    log.debugf("Handling root path - %s", name);
    final EntityDomainType entityDescriptor = getCreationContext().getJpaMetamodel().getHqlEntityReference(name);
    final HqlParser.VariableContext identificationVariableDefContext;
    if (ctx.getChildCount() > 1) {
        identificationVariableDefContext = (HqlParser.VariableContext) ctx.getChild(1);
    } else {
        identificationVariableDefContext = null;
    }
    final String alias = applyJpaCompliance(visitVariable(identificationVariableDefContext));
    final SqmCreationProcessingState processingState = processingStateStack.getCurrent();
    final SqmPathRegistry pathRegistry = processingState.getPathRegistry();
    if (entityDescriptor == null) {
        final int size = entityNameParseTreeChildren.size();
        // Handle the use of a correlation path in subqueries
        if (processingStateStack.depth() > 1 && size > 2) {
            final String parentAlias = entityNameParseTreeChildren.get(0).getText();
            final AbstractSqmFrom<?, ?> correlation = processingState.getPathRegistry().findFromByAlias(parentAlias, true);
            if (correlation instanceof SqmCorrelation<?, ?>) {
                final DotIdentifierConsumer dotIdentifierConsumer = new QualifiedJoinPathConsumer(correlation, SqmJoinType.INNER, false, alias, this);
                final int lastIdx = size - 1;
                for (int i = 2; i != lastIdx; i += 2) {
                    dotIdentifierConsumer.consumeIdentifier(entityNameParseTreeChildren.get(i).getText(), false, false);
                }
                dotIdentifierConsumer.consumeIdentifier(entityNameParseTreeChildren.get(lastIdx).getText(), false, true);
                return ((SqmCorrelation<?, ?>) correlation).getCorrelatedRoot();
            }
            throw new SemanticException("Could not resolve entity or correlation path '" + name + "'");
        }
        throw new UnknownEntityException("Could not resolve root entity '" + name + "'", name);
    }
    checkFQNEntityNameJpaComplianceViolationIfNeeded(name, entityDescriptor);
    if (entityDescriptor instanceof SqmPolymorphicRootDescriptor) {
        if (getCreationOptions().useStrictJpaCompliance()) {
            throw new StrictJpaComplianceViolation("Encountered unmapped polymorphic reference [" + entityDescriptor.getHibernateEntityName() + "], but strict JPQL compliance was requested", StrictJpaComplianceViolation.Type.UNMAPPED_POLYMORPHISM);
        }
        if (processingStateStack.depth() > 1) {
            throw new SemanticException("Illegal implicit-polymorphic domain path in subquery '" + entityDescriptor.getName() + "'");
        }
    }
    final SqmRoot<?> sqmRoot = new SqmRoot<>(entityDescriptor, alias, true, creationContext.getNodeBuilder());
    pathRegistry.register(sqmRoot);
    return sqmRoot;
}
Also used : UnknownEntityException(org.hibernate.query.sqm.UnknownEntityException) SqmRoot(org.hibernate.query.sqm.tree.from.SqmRoot) SqmCorrelation(org.hibernate.query.sqm.tree.domain.SqmCorrelation) SqmCreationProcessingState(org.hibernate.query.hql.spi.SqmCreationProcessingState) HqlParser(org.hibernate.grammars.hql.HqlParser) SqmPathRegistry(org.hibernate.query.hql.spi.SqmPathRegistry) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) DotIdentifierConsumer(org.hibernate.query.hql.spi.DotIdentifierConsumer) EntityDomainType(org.hibernate.metamodel.model.domain.EntityDomainType) SqmPolymorphicRootDescriptor(org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor) ParseTree(org.antlr.v4.runtime.tree.ParseTree) SemanticException(org.hibernate.query.SemanticException)

Example 4 with SqmCreationProcessingState

use of org.hibernate.query.hql.spi.SqmCreationProcessingState 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 5 with SqmCreationProcessingState

use of org.hibernate.query.hql.spi.SqmCreationProcessingState in project hibernate-orm by hibernate.

the class QualifiedJoinPathConsumer method resolveBase.

private ConsumerDelegate resolveBase(String identifier, boolean isTerminal) {
    final SqmCreationProcessingState processingState = creationState.getCurrentProcessingState();
    final SqmPathRegistry pathRegistry = processingState.getPathRegistry();
    final SqmFrom<?, Object> pathRootByAlias = pathRegistry.findFromByAlias(identifier, true);
    if (pathRootByAlias != null) {
        if (isTerminal) {
            throw new SemanticException("Cannot join to root '" + identifier + "'");
        }
        return new AttributeJoinDelegate(pathRootByAlias, joinType, fetch, alias, creationState);
    }
    final SqmFrom<?, Object> pathRootByExposedNavigable = pathRegistry.findFromExposing(identifier);
    if (pathRootByExposedNavigable != null) {
        return new AttributeJoinDelegate(createJoin(pathRootByExposedNavigable, identifier, isTerminal), joinType, fetch, alias, creationState);
    }
    return new ExpectingEntityJoinDelegate(identifier, isTerminal, sqmRoot, joinType, alias, fetch, creationState);
}
Also used : SqmCreationProcessingState(org.hibernate.query.hql.spi.SqmCreationProcessingState) SqmPathRegistry(org.hibernate.query.hql.spi.SqmPathRegistry) SemanticException(org.hibernate.query.SemanticException)

Aggregations

SqmCreationProcessingState (org.hibernate.query.hql.spi.SqmCreationProcessingState)6 SemanticException (org.hibernate.query.SemanticException)4 ParseTree (org.antlr.v4.runtime.tree.ParseTree)3 HqlParser (org.hibernate.grammars.hql.HqlParser)3 SqmPathRegistry (org.hibernate.query.hql.spi.SqmPathRegistry)2 StrictJpaComplianceViolation (org.hibernate.query.sqm.StrictJpaComplianceViolation)2 SqmPolymorphicRootDescriptor (org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor)2 SqmRoot (org.hibernate.query.sqm.tree.from.SqmRoot)2 SqmSelectQuery (org.hibernate.query.sqm.tree.select.SqmSelectQuery)2 SqmSubQuery (org.hibernate.query.sqm.tree.select.SqmSubQuery)2 Root (jakarta.persistence.criteria.Root)1 IDENTIFIER (org.hibernate.grammars.hql.HqlParser.IDENTIFIER)1 EntityDomainType (org.hibernate.metamodel.model.domain.EntityDomainType)1 DotIdentifierConsumer (org.hibernate.query.hql.spi.DotIdentifierConsumer)1 SetOperator (org.hibernate.query.sqm.SetOperator)1 DAY_OF_YEAR (org.hibernate.query.sqm.TemporalUnit.DAY_OF_YEAR)1 TIMEZONE_HOUR (org.hibernate.query.sqm.TemporalUnit.TIMEZONE_HOUR)1 WEEK_OF_YEAR (org.hibernate.query.sqm.TemporalUnit.WEEK_OF_YEAR)1 UnknownEntityException (org.hibernate.query.sqm.UnknownEntityException)1 SqmCreationProcessingStateImpl (org.hibernate.query.sqm.internal.SqmCreationProcessingStateImpl)1