Support usage of boolean expression in predicate context

This commit is contained in:
Christian Beikov 2021-07-08 17:20:12 +02:00
parent 87258af3f9
commit 87604549ef
4 changed files with 19 additions and 4 deletions

View File

@ -406,6 +406,7 @@ predicate
| NOT predicate # NegatedPredicate | NOT predicate # NegatedPredicate
| predicate AND predicate # AndPredicate | predicate AND predicate # AndPredicate
| predicate OR predicate # OrPredicate | predicate OR predicate # OrPredicate
| expression # BooleanExpressionPredicate
; ;
comparisonOperator comparisonOperator

View File

@ -148,6 +148,7 @@ import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
import org.hibernate.query.sqm.tree.insert.SqmValues; import org.hibernate.query.sqm.tree.insert.SqmValues;
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate; import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate; import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate; import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmEmptinessPredicate; import org.hibernate.query.sqm.tree.predicate.SqmEmptinessPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmExistsPredicate; import org.hibernate.query.sqm.tree.predicate.SqmExistsPredicate;
@ -1896,6 +1897,15 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
return new SqmExistsPredicate( expression, creationContext.getNodeBuilder() ); return new SqmExistsPredicate( expression, creationContext.getNodeBuilder() );
} }
@Override
public SqmPredicate visitBooleanExpressionPredicate(HqlParser.BooleanExpressionPredicateContext ctx) {
final SqmExpression expression = (SqmExpression) ctx.expression().accept( this );
if ( expression.getJavaType() != Boolean.class ) {
throw new SemanticException( "Non-boolean expression used in predicate context: " + ctx.getText() );
}
return new SqmBooleanExpressionPredicate( expression, creationContext.getNodeBuilder() );
}
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Object visitEntityTypeExpression(HqlParser.EntityTypeExpressionContext ctx) { public Object visitEntityTypeExpression(HqlParser.EntityTypeExpressionContext ctx) {

View File

@ -4586,14 +4586,18 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override @Override
public Object visitBooleanExpressionPredicate(SqmBooleanExpressionPredicate predicate) { public Object visitBooleanExpressionPredicate(SqmBooleanExpressionPredicate predicate) {
Object booleanExpression = predicate.getBooleanExpression().accept( this ); final Object booleanExpression = predicate.getBooleanExpression().accept( this );
if ( booleanExpression instanceof SelfRenderingExpression ) { if ( booleanExpression instanceof SelfRenderingExpression ) {
return new SelfRenderingPredicate( (SelfRenderingExpression) booleanExpression ); final Predicate sqlPredicate = new SelfRenderingPredicate( (SelfRenderingExpression) booleanExpression );
if ( predicate.isNegated() ) {
return new NegatedPredicate( sqlPredicate );
}
return sqlPredicate;
} }
else { else {
return new ComparisonPredicate( return new ComparisonPredicate(
(Expression) booleanExpression, (Expression) booleanExpression,
ComparisonOperator.EQUAL, predicate.isNegated() ? ComparisonOperator.NOT_EQUAL : ComparisonOperator.EQUAL,
new QueryLiteral<>( true, basicType( Boolean.class ) ) new QueryLiteral<>( true, basicType( Boolean.class ) )
); );
} }

View File

@ -54,7 +54,7 @@ public class QueryExceptionHandlingTest extends BaseExceptionHandlingTest {
public void testInvalidQuery() { public void testInvalidQuery() {
try { try {
TransactionUtil2.inSession( sessionFactory(), s -> { TransactionUtil2.inSession( sessionFactory(), s -> {
s.createQuery( "from A where blahblahblah" ).list(); s.createQuery( "from A a where" ).list();
} ); } );
fail( "should have thrown an exception" ); fail( "should have thrown an exception" );
} }