Use type inference for every added when/otherwise arm for case expressions

This commit is contained in:
Christian Beikov 2020-01-30 06:31:42 +01:00 committed by Steve Ebersole
parent 1cd5ea61f6
commit 7b064afbd3
2 changed files with 32 additions and 4 deletions

View File

@ -12,6 +12,7 @@ import javax.persistence.criteria.Expression;
import org.hibernate.query.criteria.JpaExpression; import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaSearchedCase; import org.hibernate.query.criteria.JpaSearchedCase;
import org.hibernate.query.internal.QueryHelper;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable; import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SemanticQueryWalker;
@ -45,12 +46,25 @@ public class SqmCaseSearched<R>
public void when(SqmPredicate predicate, SqmExpression<R> result) { public void when(SqmPredicate predicate, SqmExpression<R> result) {
whenFragments.add( new WhenFragment<>( predicate, result ) ); whenFragments.add( new WhenFragment<>( predicate, result ) );
applyInferableType( result.getNodeType() ); applyInferableResultType( result.getNodeType() );
} }
public void otherwise(SqmExpression<R> otherwiseExpression) { public void otherwise(SqmExpression<R> otherwiseExpression) {
this.otherwise = otherwiseExpression; this.otherwise = otherwiseExpression;
applyInferableType( otherwiseExpression.getNodeType() ); applyInferableResultType( otherwiseExpression.getNodeType() );
}
private void applyInferableResultType(SqmExpressable<?> type) {
if ( type == null ) {
return;
}
final SqmExpressable<?> oldType = getNodeType();
final SqmExpressable<?> newType = QueryHelper.highestPrecedenceType2( oldType, type );
if ( newType != null && newType != oldType ) {
internalApplyInferableType( newType );
}
} }
@Override @Override

View File

@ -13,6 +13,7 @@ import javax.persistence.criteria.Expression;
import org.hibernate.query.criteria.JpaExpression; import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaSimpleCase; import org.hibernate.query.criteria.JpaSimpleCase;
import org.hibernate.query.internal.QueryHelper;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable; import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SemanticQueryWalker;
@ -52,13 +53,26 @@ public class SqmCaseSimple<T,R>
public void otherwise(SqmExpression<R> otherwiseExpression) { public void otherwise(SqmExpression<R> otherwiseExpression) {
this.otherwise = otherwiseExpression; this.otherwise = otherwiseExpression;
applyInferableType( otherwiseExpression.getNodeType() ); applyInferableResultType( otherwiseExpression.getNodeType() );
} }
public void when(SqmExpression<T> test, SqmExpression<R> result) { public void when(SqmExpression<T> test, SqmExpression<R> result) {
whenFragments.add( new WhenFragment<>( test, result ) ); whenFragments.add( new WhenFragment<>( test, result ) );
applyInferableType( result.getNodeType() ); applyInferableResultType( result.getNodeType() );
}
private void applyInferableResultType(SqmExpressable<?> type) {
if ( type == null ) {
return;
}
final SqmExpressable<?> oldType = getNodeType();
final SqmExpressable<?> newType = QueryHelper.highestPrecedenceType2(oldType, type );
if ( newType != null && newType != oldType ) {
internalApplyInferableType( newType );
}
} }
@Override @Override