HHH-17766 Correct return type of by duration and numeric operations on converted attributes
This commit is contained in:
parent
c6e41c6f21
commit
f87ea083e6
|
@ -398,8 +398,8 @@ public class TypecheckUtil {
|
||||||
final SqmExpressible<?> leftNodeType = left.getNodeType();
|
final SqmExpressible<?> leftNodeType = left.getNodeType();
|
||||||
final SqmExpressible<?> rightNodeType = right.getNodeType();
|
final SqmExpressible<?> rightNodeType = right.getNodeType();
|
||||||
if ( leftNodeType != null && rightNodeType != null ) {
|
if ( leftNodeType != null && rightNodeType != null ) {
|
||||||
final Class<?> leftJavaType = leftNodeType.getExpressibleJavaType().getJavaTypeClass();
|
final Class<?> leftJavaType = leftNodeType.getRelationalJavaType().getJavaTypeClass();
|
||||||
final Class<?> rightJavaType = rightNodeType.getExpressibleJavaType().getJavaTypeClass();
|
final Class<?> rightJavaType = rightNodeType.getRelationalJavaType().getJavaTypeClass();
|
||||||
if ( Number.class.isAssignableFrom( leftJavaType ) ) {
|
if ( Number.class.isAssignableFrom( leftJavaType ) ) {
|
||||||
// left operand is a number
|
// left operand is a number
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -494,7 +494,7 @@ public class TypecheckUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNumberArray(SqmExpressible<?> expressible) {
|
public static boolean isNumberArray(SqmExpressible<?> expressible) {
|
||||||
final DomainType<?> domainType;
|
final DomainType<?> domainType;
|
||||||
if ( expressible != null && ( domainType = expressible.getSqmType() ) != null ) {
|
if ( expressible != null && ( domainType = expressible.getSqmType() ) != null ) {
|
||||||
return domainType instanceof BasicPluralType<?, ?> && Number.class.isAssignableFrom(
|
return domainType instanceof BasicPluralType<?, ?> && Number.class.isAssignableFrom(
|
||||||
|
|
|
@ -6366,7 +6366,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
return new UnaryOperation(
|
return new UnaryOperation(
|
||||||
interpret( expression.getOperation() ),
|
interpret( expression.getOperation() ),
|
||||||
toSqlExpression( expression.getOperand().accept( this ) ),
|
toSqlExpression( expression.getOperand().accept( this ) ),
|
||||||
(BasicValuedMapping) determineValueMapping( expression.getOperand() )
|
getExpressionType( expression )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6429,7 +6429,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BasicValuedMapping getExpressionType(SqmBinaryArithmetic<?> expression) {
|
private BasicValuedMapping getExpressionType(SqmExpression<?> expression) {
|
||||||
final SqmExpressible<?> nodeType = expression.getNodeType();
|
final SqmExpressible<?> nodeType = expression.getNodeType();
|
||||||
if ( nodeType != null ) {
|
if ( nodeType != null ) {
|
||||||
if ( nodeType instanceof BasicValuedMapping ) {
|
if ( nodeType instanceof BasicValuedMapping ) {
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.query.sqm.tree.expression;
|
package org.hibernate.query.sqm.tree.expression;
|
||||||
|
|
||||||
import org.hibernate.query.sqm.UnaryArithmeticOperator;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
|
import org.hibernate.query.sqm.UnaryArithmeticOperator;
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||||
|
|
||||||
|
@ -19,10 +20,14 @@ public class SqmUnaryOperation<T> extends AbstractSqmExpression<T> implements Sq
|
||||||
private final UnaryArithmeticOperator operation;
|
private final UnaryArithmeticOperator operation;
|
||||||
private final SqmExpression<T> operand;
|
private final SqmExpression<T> operand;
|
||||||
|
|
||||||
public SqmUnaryOperation(
|
public SqmUnaryOperation(UnaryArithmeticOperator operation, SqmExpression<T> operand) {
|
||||||
UnaryArithmeticOperator operation,
|
this(
|
||||||
SqmExpression<T> operand) {
|
operation,
|
||||||
this( operation, operand, operand.getNodeType() );
|
operand,
|
||||||
|
operand.nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType(
|
||||||
|
operand.getNodeType().getRelationalJavaType().getJavaType()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SqmUnaryOperation(
|
public SqmUnaryOperation(
|
||||||
|
|
|
@ -80,6 +80,7 @@ import org.hibernate.type.internal.ParameterizedTypeImpl;
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
import static org.hibernate.internal.CoreLogging.messageLogger;
|
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||||
|
import static org.hibernate.query.sqm.internal.TypecheckUtil.isNumberArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each instance defines a set of {@linkplain Type types} available in a given
|
* Each instance defines a set of {@linkplain Type types} available in a given
|
||||||
|
@ -679,16 +680,24 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
return getBasicTypeRegistry().getRegisteredType( Duration.class );
|
return getBasicTypeRegistry().getRegisteredType( Duration.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( secondType == null || firstType != null
|
if ( firstType != null && ( secondType == null
|
||||||
&& firstType.getExpressibleJavaType().isWider( secondType.getExpressibleJavaType() ) ) {
|
|| firstType.getRelationalJavaType().isWider( secondType.getRelationalJavaType() ) ) ) {
|
||||||
return firstType;
|
return resolveBasicArithmeticType( firstType );
|
||||||
}
|
}
|
||||||
return secondType;
|
return secondType != null ? resolveBasicArithmeticType( secondType ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BasicType<?> resolveBasicArithmeticType(SqmExpressible<?> expressible) {
|
||||||
|
if ( isNumberArray( expressible ) ) {
|
||||||
|
return (BasicType<?>) expressible.getSqmType();
|
||||||
|
}
|
||||||
|
// Use the relational java type to account for possible converters
|
||||||
|
return getBasicTypeForJavaType( expressible.getRelationalJavaType().getJavaTypeClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean matchesJavaType(SqmExpressible<?> type, Class<?> javaType) {
|
private static boolean matchesJavaType(SqmExpressible<?> type, Class<?> javaType) {
|
||||||
assert javaType != null;
|
assert javaType != null;
|
||||||
return type != null && javaType.isAssignableFrom( type.getExpressibleJavaType().getJavaTypeClass() );
|
return type != null && javaType.isAssignableFrom( type.getRelationalJavaType().getJavaTypeClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -778,7 +787,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
if ( type == null ) {
|
if ( type == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getSqlTemporalType( type.getExpressibleJavaType().getRecommendedJdbcType( getCurrentBaseSqlTypeIndicators() ) );
|
return getSqlTemporalType( type.getRelationalJavaType().getRecommendedJdbcType( getCurrentBaseSqlTypeIndicators() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TemporalType getSqlTemporalType(JdbcMapping jdbcMapping) {
|
public static TemporalType getSqlTemporalType(JdbcMapping jdbcMapping) {
|
||||||
|
|
Loading…
Reference in New Issue