Fix type inference for case expressions and simple case SQL rendering issue
This commit is contained in:
parent
f66728d5b2
commit
1cd5ea61f6
|
@ -47,6 +47,7 @@ import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
|
|||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
|
@ -697,6 +698,10 @@ public class MappingMetamodelImpl implements MappingMetamodel, MetamodelImplemen
|
|||
return (BasicType) sqmExpressable;
|
||||
}
|
||||
|
||||
if ( sqmExpressable instanceof BasicSqmPathSource<?> ) {
|
||||
return getTypeConfiguration().getBasicTypeForJavaType(((BasicSqmPathSource<?>) sqmExpressable).getJavaType());
|
||||
}
|
||||
|
||||
if ( sqmExpressable instanceof CompositeSqmPathSource ) {
|
||||
throw new NotYetImplementedFor6Exception( "Resolution of embedded-valued SqmExpressable nodes not yet implemented" );
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.query.BinaryArithmeticOperator;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.UnaryArithmeticOperator;
|
||||
import org.hibernate.query.internal.QueryHelper;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.spi.QueryParameterBinding;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
|
@ -838,6 +839,23 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
);
|
||||
}
|
||||
|
||||
protected MappingModelExpressable<?> resolveMappingExpressable(SqmExpressable<?> nodeType) {
|
||||
final MappingModelExpressable valueMapping = getCreationContext().getDomainModel().resolveMappingExpressable( nodeType );
|
||||
|
||||
if ( valueMapping == null ) {
|
||||
final Supplier<MappingModelExpressable> currentExpressableSupplier = inferableTypeAccessStack.getCurrent();
|
||||
if ( currentExpressableSupplier != null ) {
|
||||
return currentExpressableSupplier.get();
|
||||
}
|
||||
}
|
||||
|
||||
if ( valueMapping == null ) {
|
||||
throw new ConversionException( "Could not determine ValueMapping for SqmExpressable: " + nodeType );
|
||||
}
|
||||
|
||||
return valueMapping;
|
||||
}
|
||||
|
||||
protected MappingModelExpressable<?> determineValueMapping(SqmExpression<?> sqmExpression) {
|
||||
if ( sqmExpression instanceof SqmParameter ) {
|
||||
return determineValueMapping( (SqmParameter) sqmExpression );
|
||||
|
@ -871,7 +889,6 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
return valueMapping;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected MappingModelExpressable<?> determineValueMapping(SqmParameter<?> sqmParameter) {
|
||||
log.debugf( "Determining mapping-model type for SqmParameter : %s", sqmParameter );
|
||||
|
@ -1486,37 +1503,59 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
|
||||
@Override
|
||||
public CaseSimpleExpression visitSimpleCaseExpression(SqmCaseSimple<?,?> expression) {
|
||||
final CaseSimpleExpression result = new CaseSimpleExpression(
|
||||
determineValueMapping( expression ),
|
||||
(Expression) expression.getFixture().accept( this )
|
||||
);
|
||||
|
||||
for ( SqmCaseSimple.WhenFragment whenFragment : expression.getWhenFragments() ) {
|
||||
result.when(
|
||||
(Expression) whenFragment.getCheckValue().accept( this ),
|
||||
(Expression) whenFragment.getResult().accept( this )
|
||||
SqmExpressable<?> resultType = expression.getNodeType();
|
||||
List<CaseSimpleExpression.WhenFragment> whenFragments = new ArrayList<>( expression.getWhenFragments().size() );
|
||||
for ( SqmCaseSimple.WhenFragment<?, ?> whenFragment : expression.getWhenFragments() ) {
|
||||
resultType = QueryHelper.highestPrecedenceType2( resultType, whenFragment.getResult().getNodeType() );
|
||||
whenFragments.add(
|
||||
new CaseSimpleExpression.WhenFragment(
|
||||
(Expression) whenFragment.getCheckValue().accept(this),
|
||||
(Expression) whenFragment.getResult().accept(this)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
result.otherwise( (Expression) expression.getOtherwise().accept( this ) );
|
||||
Expression otherwise = null;
|
||||
if ( expression.getOtherwise() != null ) {
|
||||
resultType = QueryHelper.highestPrecedenceType2( resultType, expression.getOtherwise().getNodeType() );
|
||||
otherwise = (Expression) expression.getOtherwise().accept(this );
|
||||
}
|
||||
|
||||
final CaseSimpleExpression result = new CaseSimpleExpression(
|
||||
resolveMappingExpressable( resultType ),
|
||||
(Expression) expression.getFixture().accept( this ),
|
||||
whenFragments,
|
||||
otherwise
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseSearchedExpression visitSearchedCaseExpression(SqmCaseSearched<?> expression) {
|
||||
final CaseSearchedExpression result = new CaseSearchedExpression(
|
||||
determineValueMapping( expression )
|
||||
);
|
||||
|
||||
for ( SqmCaseSearched.WhenFragment whenFragment : expression.getWhenFragments() ) {
|
||||
result.when(
|
||||
(Predicate) whenFragment.getPredicate().accept( this ),
|
||||
(Expression) whenFragment.getResult().accept( this )
|
||||
SqmExpressable<?> resultType = expression.getNodeType();
|
||||
List<CaseSearchedExpression.WhenFragment> whenFragments = new ArrayList<>( expression.getWhenFragments().size() );
|
||||
for ( SqmCaseSearched.WhenFragment<?> whenFragment : expression.getWhenFragments() ) {
|
||||
resultType = QueryHelper.highestPrecedenceType2( resultType, whenFragment.getResult().getNodeType() );
|
||||
whenFragments.add(
|
||||
new CaseSearchedExpression.WhenFragment(
|
||||
(Predicate) whenFragment.getPredicate().accept(this),
|
||||
(Expression) whenFragment.getResult().accept(this)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
result.otherwise( (Expression) expression.getOtherwise().accept( this ) );
|
||||
Expression otherwise = null;
|
||||
if ( expression.getOtherwise() != null ) {
|
||||
resultType = QueryHelper.highestPrecedenceType2( resultType, expression.getOtherwise().getNodeType() );
|
||||
otherwise = (Expression) expression.getOtherwise().accept(this );
|
||||
}
|
||||
|
||||
final CaseSearchedExpression result = new CaseSearchedExpression(
|
||||
resolveMappingExpressable( resultType ),
|
||||
whenFragments,
|
||||
otherwise
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -818,7 +818,7 @@ public abstract class AbstractSqlAstWalker
|
|||
|
||||
@Override
|
||||
public void visitCaseSimpleExpression(CaseSimpleExpression caseSimpleExpression) {
|
||||
appendSql( " case" );
|
||||
appendSql( "case " );
|
||||
caseSimpleExpression.getFixture().accept( this );
|
||||
for ( CaseSimpleExpression.WhenFragment whenFragment : caseSimpleExpression.getWhenFragments() ) {
|
||||
appendSql( " when " );
|
||||
|
|
|
@ -36,6 +36,12 @@ public class CaseSearchedExpression implements Expression, DomainResultProducer
|
|||
this.type = (BasicType) type;
|
||||
}
|
||||
|
||||
public CaseSearchedExpression(MappingModelExpressable type, List<WhenFragment> whenFragments, Expression otherwise) {
|
||||
this.type = (BasicType) type;
|
||||
this.whenFragments = whenFragments;
|
||||
this.otherwise = otherwise;
|
||||
}
|
||||
|
||||
public List<WhenFragment> getWhenFragments() {
|
||||
return whenFragments;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,13 @@ public class CaseSimpleExpression implements Expression, DomainResultProducer {
|
|||
this.fixture = fixture;
|
||||
}
|
||||
|
||||
public CaseSimpleExpression(MappingModelExpressable type, Expression fixture, List<WhenFragment> whenFragments, Expression otherwise) {
|
||||
this.type = type;
|
||||
this.fixture = fixture;
|
||||
this.whenFragments = whenFragments;
|
||||
this.otherwise = otherwise;
|
||||
}
|
||||
|
||||
public Expression getFixture() {
|
||||
return fixture;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue