Search in sources :

Example 1 with ParsingException

use of org.hibernate.query.sqm.ParsingException in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method resolveOrderByOrGroupByExpression.

private SqmExpression<?> resolveOrderByOrGroupByExpression(ParseTree child, boolean definedCollate) {
    if (child instanceof TerminalNode) {
        if (definedCollate) {
            // This is syntactically disallowed
            throw new ParsingException("COLLATE is not allowed for position based order-by or group-by items");
        }
        final int position = Integer.parseInt(child.getText());
        // make sure this selection exists
        final SqmAliasedNode<?> nodeByPosition = getCurrentProcessingState().getPathRegistry().findAliasedNodeByPosition(position);
        if (nodeByPosition == null) {
            throw new ParsingException("Numeric literal '" + position + "' used in group-by does not match a registered select-item");
        }
        return new SqmAliasedNodeRef(position, integerDomainType, creationContext.getNodeBuilder());
    } else if (child instanceof HqlParser.IdentifierContext) {
        final String identifierText = visitIdentifier((HqlParser.IdentifierContext) child);
        final Integer correspondingPosition = getCurrentProcessingState().getPathRegistry().findAliasedNodePosition(identifierText);
        if (correspondingPosition != null) {
            if (definedCollate) {
                // This is syntactically disallowed
                throw new ParsingException("COLLATE is not allowed for alias based order-by or group-by items");
            }
            return new SqmAliasedNodeRef(correspondingPosition, integerDomainType, creationContext.getNodeBuilder());
        }
        final SqmFrom<?, ?> sqmFrom = getCurrentProcessingState().getPathRegistry().findFromByAlias(identifierText, true);
        if (sqmFrom != null) {
            if (definedCollate) {
                // This is syntactically disallowed
                throw new ParsingException("COLLATE is not allowed for alias based order-by or group-by items");
            }
            // this will group-by all of the sub-parts in the from-element's model part
            return sqmFrom;
        }
        final DotIdentifierConsumer dotIdentifierConsumer = dotIdentifierConsumerStack.getCurrent();
        dotIdentifierConsumer.consumeIdentifier(identifierText, true, true);
        return (SqmExpression<?>) dotIdentifierConsumer.getConsumedPart();
    }
    return (SqmExpression<?>) child.accept(this);
}
Also used : SqmAliasedNodeRef(org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef) SqmFrom(org.hibernate.query.sqm.tree.from.SqmFrom) AbstractSqmFrom(org.hibernate.query.sqm.tree.domain.AbstractSqmFrom) BigInteger(java.math.BigInteger) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) ParsingException(org.hibernate.query.sqm.ParsingException) HqlParser(org.hibernate.grammars.hql.HqlParser) DotIdentifierConsumer(org.hibernate.query.hql.spi.DotIdentifierConsumer) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode)

Example 2 with ParsingException

use of org.hibernate.query.sqm.ParsingException in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitStatement.

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Grammar rules
@Override
public SqmStatement<R> visitStatement(HqlParser.StatementContext ctx) {
    // parameters allow multi-valued bindings only in very limited cases, so for
    // the base case here we say false
    parameterDeclarationContextStack.push(() -> false);
    try {
        final ParseTree parseTree = ctx.getChild(0);
        if (parseTree instanceof HqlParser.SelectStatementContext) {
            final SqmSelectStatement<R> selectStatement = visitSelectStatement((HqlParser.SelectStatementContext) parseTree);
            selectStatement.getQueryPart().validateQueryStructureAndFetchOwners();
            return selectStatement;
        } else if (parseTree instanceof HqlParser.InsertStatementContext) {
            return visitInsertStatement((HqlParser.InsertStatementContext) parseTree);
        } else if (parseTree instanceof HqlParser.UpdateStatementContext) {
            return visitUpdateStatement((HqlParser.UpdateStatementContext) parseTree);
        } else if (parseTree instanceof HqlParser.DeleteStatementContext) {
            return visitDeleteStatement((HqlParser.DeleteStatementContext) parseTree);
        }
    } finally {
        parameterDeclarationContextStack.pop();
    }
    throw new ParsingException("Unexpected statement type [not INSERT, UPDATE, DELETE or SELECT] : " + ctx.getText());
}
Also used : 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) HqlParser(org.hibernate.grammars.hql.HqlParser) ParsingException(org.hibernate.query.sqm.ParsingException) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Example 3 with ParsingException

use of org.hibernate.query.sqm.ParsingException in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitCollectionFunctionMisuse.

@Override
public SqmPath<?> visitCollectionFunctionMisuse(HqlParser.CollectionFunctionMisuseContext ctx) {
    if (getCreationOptions().useStrictJpaCompliance()) {
        throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.HQL_COLLECTION_FUNCTION);
    }
    final SqmPath<?> pluralAttributePath = consumeDomainPath((HqlParser.PathContext) ctx.getChild(2));
    final SqmPathSource<?> referencedPathSource = pluralAttributePath.getReferencedPathSource();
    final TerminalNode firstNode = (TerminalNode) ctx.getChild(0);
    if (!(referencedPathSource instanceof PluralPersistentAttribute<?, ?, ?>)) {
        throw new PathException(String.format("Argument of '%s' is not a plural path '%s'", firstNode.getSymbol().getText(), pluralAttributePath.getNavigablePath()));
    }
    CollectionPart.Nature nature;
    switch(firstNode.getSymbol().getType()) {
        case ELEMENTS:
            nature = CollectionPart.Nature.ELEMENT;
            break;
        case INDICES:
            nature = CollectionPart.Nature.INDEX;
            break;
        default:
            throw new ParsingException("Impossible symbol");
    }
    return pluralAttributePath.resolvePathPart(nature.getName(), true, this);
}
Also used : PathException(org.hibernate.query.PathException) PluralPersistentAttribute(org.hibernate.metamodel.model.domain.PluralPersistentAttribute) HqlParser(org.hibernate.grammars.hql.HqlParser) ParsingException(org.hibernate.query.sqm.ParsingException) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) CollectionPart(org.hibernate.metamodel.mapping.CollectionPart)

Example 4 with ParsingException

use of org.hibernate.query.sqm.ParsingException in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitGenericFunction.

@Override
public Object visitGenericFunction(HqlParser.GenericFunctionContext ctx) {
    final String originalFunctionName = visitGenericFunctionName(ctx.genericFunctionName());
    final String functionName = originalFunctionName.toLowerCase();
    if (creationOptions.useStrictJpaCompliance() && !JPA_STANDARD_FUNCTIONS.contains(functionName)) {
        throw new StrictJpaComplianceViolation("Encountered non-compliant non-standard function call [" + originalFunctionName + "], but strict JPA " + "compliance was requested; use JPA's FUNCTION(functionName[,...]) " + "syntax name instead", StrictJpaComplianceViolation.Type.FUNCTION_CALL);
    }
    final ParseTree argumentChild = ctx.getChild(2);
    final List<SqmTypedNode<?>> functionArguments;
    if (argumentChild instanceof HqlParser.GenericFunctionArgumentsContext) {
        functionArguments = (List<SqmTypedNode<?>>) argumentChild.accept(this);
    } else if ("*".equals(argumentChild.getText())) {
        functionArguments = Collections.singletonList(new SqmStar(getCreationContext().getNodeBuilder()));
    } else {
        functionArguments = emptyList();
    }
    final Boolean fromFirst = getFromFirst(ctx);
    final Boolean respectNulls = getRespectNullsClause(ctx);
    final SqmOrderByClause withinGroup = getWithinGroup(ctx);
    final SqmPredicate filterExpression = getFilterExpression(ctx);
    final boolean hasOverClause = ctx.getChild(ctx.getChildCount() - 1) instanceof HqlParser.OverClauseContext;
    SqmFunctionDescriptor functionTemplate = getFunctionDescriptor(functionName);
    if (functionTemplate == null) {
        FunctionKind functionKind = FunctionKind.NORMAL;
        if (withinGroup != null) {
            functionKind = FunctionKind.ORDERED_SET_AGGREGATE;
        } else if (hasOverClause) {
            functionKind = FunctionKind.WINDOW;
        } else if (filterExpression != null) {
            functionKind = FunctionKind.AGGREGATE;
        }
        functionTemplate = new NamedSqmFunctionDescriptor(functionName, true, null, StandardFunctionReturnTypeResolvers.invariant(resolveExpressibleTypeBasic(Object.class)), null, functionName, functionKind, null, SqlAstNodeRenderingMode.DEFAULT);
    } else {
        if (hasOverClause && functionTemplate.getFunctionKind() == FunctionKind.NORMAL) {
            throw new SemanticException("OVER clause is illegal for normal function: " + functionName);
        } else if (!hasOverClause && functionTemplate.getFunctionKind() == FunctionKind.WINDOW) {
            throw new SemanticException("OVER clause is mandatory for window-only function: " + functionName);
        }
        if (respectNulls != null) {
            switch(functionName) {
                case "lag":
                case "lead":
                case "first_value":
                case "last_value":
                case "nth_value":
                    break;
                default:
                    throw new SemanticException("RESPECT/IGNORE NULLS is illegal for function: " + functionName);
            }
        }
        if (fromFirst != null && !"nth_value".equals(functionName)) {
            throw new SemanticException("FROM FIRST/LAST is illegal for function: " + functionName);
        }
    }
    final SqmFunction<?> function;
    switch(functionTemplate.getFunctionKind()) {
        case ORDERED_SET_AGGREGATE:
            function = functionTemplate.generateOrderedSetAggregateSqmExpression(functionArguments, filterExpression, withinGroup, null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
            break;
        case AGGREGATE:
            function = functionTemplate.generateAggregateSqmExpression(functionArguments, filterExpression, null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
            break;
        case WINDOW:
            function = functionTemplate.generateWindowSqmExpression(functionArguments, filterExpression, null, null, null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
            break;
        default:
            if (filterExpression != null) {
                throw new ParsingException("Illegal use of a FILTER clause for non-aggregate function: " + originalFunctionName);
            }
            function = functionTemplate.generateSqmExpression(functionArguments, null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
            break;
    }
    return applyOverClause(ctx, function);
}
Also used : SqmStar(org.hibernate.query.sqm.tree.expression.SqmStar) SqmPredicate(org.hibernate.query.sqm.tree.predicate.SqmPredicate) NamedSqmFunctionDescriptor(org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor) NamedSqmFunctionDescriptor(org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor) SqmFunctionDescriptor(org.hibernate.query.sqm.function.SqmFunctionDescriptor) SqmTypedNode(org.hibernate.query.sqm.tree.SqmTypedNode) ParsingException(org.hibernate.query.sqm.ParsingException) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) FunctionKind(org.hibernate.query.sqm.function.FunctionKind) ParseTree(org.antlr.v4.runtime.tree.ParseTree) SqmOrderByClause(org.hibernate.query.sqm.tree.select.SqmOrderByClause) SemanticException(org.hibernate.query.SemanticException)

Example 5 with ParsingException

use of org.hibernate.query.sqm.ParsingException in project hibernate-orm by hibernate.

the class SemanticQueryBuilder method visitInPredicate.

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public SqmPredicate visitInPredicate(HqlParser.InPredicateContext ctx) {
    final boolean negated = ctx.getChildCount() == 4;
    final SqmExpression<?> testExpression = (SqmExpression<?>) ctx.getChild(0).accept(this);
    final HqlParser.InListContext inListContext = (HqlParser.InListContext) ctx.getChild(ctx.getChildCount() - 1);
    if (inListContext instanceof HqlParser.ExplicitTupleInListContext) {
        final HqlParser.ExplicitTupleInListContext tupleExpressionListContext = (HqlParser.ExplicitTupleInListContext) inListContext;
        final int size = tupleExpressionListContext.getChildCount();
        final int estimatedSize = size >> 1;
        final Class<?> testExpressionJavaType = testExpression.getJavaType();
        final boolean isEnum = testExpressionJavaType != null && testExpressionJavaType.isEnum();
        // Multi-valued bindings are only allowed if there is a single list item, hence size 3 (LP, RP and param)
        parameterDeclarationContextStack.push(() -> size == 3);
        try {
            final List<SqmExpression<?>> listExpressions = new ArrayList<>(estimatedSize);
            for (int i = 1; i < size; i++) {
                final ParseTree parseTree = tupleExpressionListContext.getChild(i);
                if (parseTree instanceof HqlParser.ExpressionOrPredicateContext) {
                    final ParseTree child = parseTree.getChild(0);
                    final HqlParser.ExpressionContext expressionContext;
                    final Map<Class<?>, Enum<?>> possibleEnumValues;
                    if (isEnum && child instanceof HqlParser.ExpressionContext && (possibleEnumValues = getPossibleEnumValues(expressionContext = (HqlParser.ExpressionContext) child)) != null) {
                        listExpressions.add(resolveEnumShorthandLiteral(expressionContext, possibleEnumValues, testExpressionJavaType));
                    } else {
                        listExpressions.add((SqmExpression<?>) child.accept(this));
                    }
                }
            }
            return new SqmInListPredicate(testExpression, listExpressions, negated, creationContext.getNodeBuilder());
        } finally {
            parameterDeclarationContextStack.pop();
        }
    } else if (inListContext instanceof HqlParser.ParamInListContext) {
        final HqlParser.ParamInListContext tupleExpressionListContext = (HqlParser.ParamInListContext) inListContext;
        parameterDeclarationContextStack.push(() -> true);
        try {
            return new SqmInListPredicate(testExpression, Collections.singletonList(tupleExpressionListContext.getChild(0).accept(this)), negated, creationContext.getNodeBuilder());
        } finally {
            parameterDeclarationContextStack.pop();
        }
    } else if (inListContext instanceof HqlParser.SubqueryInListContext) {
        final HqlParser.SubqueryInListContext subQueryOrParamInListContext = (HqlParser.SubqueryInListContext) inListContext;
        return new SqmInSubQueryPredicate(testExpression, visitSubquery((HqlParser.SubqueryContext) subQueryOrParamInListContext.getChild(1)), negated, creationContext.getNodeBuilder());
    } else if (inListContext instanceof HqlParser.PersistentCollectionReferenceInListContext) {
        if (getCreationOptions().useStrictJpaCompliance()) {
            throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.HQL_COLLECTION_FUNCTION);
        }
        final HqlParser.PersistentCollectionReferenceInListContext collectionReferenceInListContext = (HqlParser.PersistentCollectionReferenceInListContext) inListContext;
        return new SqmInSubQueryPredicate<>(testExpression, createCollectionReferenceSubQuery((HqlParser.SimplePathContext) collectionReferenceInListContext.getChild(2), (TerminalNode) collectionReferenceInListContext.getChild(0)), negated, creationContext.getNodeBuilder());
    } else {
        throw new ParsingException("Unexpected IN predicate type [" + ctx.getClass().getSimpleName() + "] : " + ctx.getText());
    }
}
Also used : ArrayList(java.util.ArrayList) SqmInSubQueryPredicate(org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate) ParsingException(org.hibernate.query.sqm.ParsingException) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) HqlParser(org.hibernate.grammars.hql.HqlParser) StrictJpaComplianceViolation(org.hibernate.query.sqm.StrictJpaComplianceViolation) SqmInListPredicate(org.hibernate.query.sqm.tree.predicate.SqmInListPredicate) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Aggregations

ParsingException (org.hibernate.query.sqm.ParsingException)11 HqlParser (org.hibernate.grammars.hql.HqlParser)6 ParseTree (org.antlr.v4.runtime.tree.ParseTree)4 SemanticException (org.hibernate.query.SemanticException)4 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)3 StrictJpaComplianceViolation (org.hibernate.query.sqm.StrictJpaComplianceViolation)3 SqmExpression (org.hibernate.query.sqm.tree.expression.SqmExpression)3 BigInteger (java.math.BigInteger)2 ArrayList (java.util.ArrayList)2 PluralPersistentAttribute (org.hibernate.metamodel.model.domain.PluralPersistentAttribute)2 PathException (org.hibernate.query.PathException)2 SqmLiteral (org.hibernate.query.sqm.tree.expression.SqmLiteral)2 EntityExistsException (jakarta.persistence.EntityExistsException)1 EntityNotFoundException (jakarta.persistence.EntityNotFoundException)1 LockTimeoutException (jakarta.persistence.LockTimeoutException)1 NoResultException (jakarta.persistence.NoResultException)1 NonUniqueResultException (jakarta.persistence.NonUniqueResultException)1 OptimisticLockException (jakarta.persistence.OptimisticLockException)1 PersistenceException (jakarta.persistence.PersistenceException)1 PessimisticLockException (jakarta.persistence.PessimisticLockException)1