use of org.hibernate.query.sqm.tree.predicate.SqmInListPredicate in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitInListPredicate.
@Override
public Predicate visitInListPredicate(SqmInListPredicate<?> predicate) {
// handling for "expansion"
if (predicate.getListExpressions().size() == 1) {
final SqmExpression<?> sqmExpression = predicate.getListExpressions().get(0);
if (sqmExpression instanceof SqmParameter) {
final SqmParameter<?> sqmParameter = (SqmParameter<?>) sqmExpression;
if (sqmParameter.allowMultiValuedBinding()) {
final Predicate specialCase = processInListWithSingleParameter(predicate, sqmParameter);
if (specialCase != null) {
return specialCase;
}
}
}
}
// otherwise - no special case...
final FromClauseIndex fromClauseIndex = fromClauseIndexStack.getCurrent();
inferrableTypeAccessStack.push(() -> {
for (SqmExpression<?> listExpression : predicate.getListExpressions()) {
final MappingModelExpressible<?> mapping = determineValueMapping(listExpression, fromClauseIndex);
if (mapping != null) {
return mapping;
}
}
return null;
});
final Expression testExpression;
try {
testExpression = (Expression) predicate.getTestExpression().accept(this);
} finally {
inferrableTypeAccessStack.pop();
}
final InListPredicate inPredicate = new InListPredicate(testExpression, predicate.isNegated(), getBooleanType());
inferrableTypeAccessStack.push(() -> determineValueMapping(predicate.getTestExpression(), fromClauseIndex));
try {
for (SqmExpression<?> expression : predicate.getListExpressions()) {
inPredicate.addExpression((Expression) expression.accept(this));
}
} finally {
inferrableTypeAccessStack.pop();
}
return inPredicate;
}
use of org.hibernate.query.sqm.tree.predicate.SqmInListPredicate 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());
}
}
use of org.hibernate.query.sqm.tree.predicate.SqmInListPredicate in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method processInSingleParameter.
private Predicate processInSingleParameter(SqmInListPredicate<?> sqmPredicate, SqmParameter<?> sqmParameter, QueryParameterImplementor<?> domainParam, QueryParameterBinding<?> domainParamBinding) {
final Iterator<?> iterator = domainParamBinding.getBindValues().iterator();
final InListPredicate inListPredicate = new InListPredicate((Expression) sqmPredicate.getTestExpression().accept(this), sqmPredicate.isNegated(), getBooleanType());
if (!iterator.hasNext()) {
return inListPredicate;
}
final FromClauseIndex fromClauseIndex = fromClauseIndexStack.getCurrent();
inferrableTypeAccessStack.push(() -> determineValueMapping(sqmPredicate.getTestExpression(), fromClauseIndex));
try {
inListPredicate.addExpression(consumeSingleSqmParameter(sqmParameter));
iterator.next();
while (iterator.hasNext()) {
iterator.next();
// for each bind value create an "expansion"
final SqmParameter<?> sqmParamToConsume = sqmParameter.copy();
domainParameterXref.addExpansion(domainParam, sqmParameter, sqmParamToConsume);
inListPredicate.addExpression(consumeSingleSqmParameter(sqmParamToConsume));
}
return inListPredicate;
} finally {
inferrableTypeAccessStack.pop();
}
}
Aggregations