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);
}
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());
}
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);
}
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);
}
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());
}
}
Aggregations