Allow implicit casting of types if implied and actual type are both numeric and change floor/ceil to return argument type

This commit is contained in:
Christian Beikov 2021-01-25 22:23:19 +01:00
parent 5d768af983
commit e1aa2d941f
4 changed files with 26 additions and 20 deletions

View File

@ -809,7 +809,8 @@ public class CommonFunctionFactory {
public static void ceiling_ceil(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "ceil" )
.setExactArgumentCount( 1 )
.setInvariantType( StandardBasicTypes.DOUBLE )
// To avoid truncating to a specific data type, we default to using the argument type
.setReturnTypeResolver( useArgType(1) )
.register();
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "ceiling", "ceil" );
}
@ -1463,12 +1464,14 @@ public class CommonFunctionFactory {
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("floor")
.setInvariantType( StandardBasicTypes.LONG )
// To avoid truncating to a specific data type, we default to using the argument type
.setReturnTypeResolver( useArgType(1) )
.setExactArgumentCount(1)
.register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("ceiling")
.setInvariantType( StandardBasicTypes.LONG )
// To avoid truncating to a specific data type, we default to using the argument type
.setReturnTypeResolver( useArgType(1) )
.setExactArgumentCount(1)
.register();

View File

@ -154,7 +154,7 @@ public class ExtractFunction
intType,
builder
),
intType,
intType, // Implicit cast to int
queryEngine,
typeConfiguration
);
@ -177,7 +177,7 @@ public class ExtractFunction
.findFunctionDescriptor("floor")
.generateSqmExpression(
arg,
longType,
longType, // Implicit cast to long
queryEngine,
typeConfiguration
);

View File

@ -2960,7 +2960,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionDescriptor("ceiling").generateSqmExpression(
arg,
resolveExpressableTypeBasic( Long.class ),
(AllowableFunctionReturnType<?>) arg.getNodeType(),
creationContext.getQueryEngine(),
creationContext.getJpaMetamodel().getTypeConfiguration()
);
@ -2972,7 +2972,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionDescriptor("floor").generateSqmExpression(
arg,
resolveExpressableTypeBasic( Long.class ),
(AllowableFunctionReturnType<?>) arg.getNodeType(),
creationContext.getQueryEngine(),
creationContext.getJpaMetamodel().getTypeConfiguration()
);

View File

@ -140,8 +140,7 @@ public class StandardFunctionReturnTypeResolvers {
int impliedTypeCode = ((BasicType<?>) implied).getJdbcMapping().getSqlTypeDescriptor().getJdbcTypeCode();
int definedTypeCode = ((BasicType<?>) defined).getJdbcMapping().getSqlTypeDescriptor().getJdbcTypeCode();
return impliedTypeCode == definedTypeCode
|| isInteger(impliedTypeCode) && isInteger(definedTypeCode)
|| isFloat(impliedTypeCode) && isFloat(definedTypeCode);
|| isNumeric( impliedTypeCode ) && isNumeric( definedTypeCode );
}
private static BasicValuedMapping useImpliedTypeIfPossible(
@ -181,20 +180,24 @@ public class StandardFunctionReturnTypeResolvers {
int impliedTypeCode = implied.getJdbcMapping().getSqlTypeDescriptor().getJdbcTypeCode();
int definedTypeCode = defined.getJdbcMapping().getSqlTypeDescriptor().getJdbcTypeCode();
return impliedTypeCode == definedTypeCode
|| isInteger(impliedTypeCode) && isInteger(definedTypeCode)
|| isFloat(impliedTypeCode) && isFloat(definedTypeCode);
|| isNumeric( impliedTypeCode ) && isNumeric( definedTypeCode );
}
private static boolean isInteger(int type) {
return type == Types.INTEGER
|| type == Types.BIGINT
|| type == Types.SMALLINT
|| type == Types.TINYINT;
}
private static boolean isFloat(int type) {
return type == Types.FLOAT || type == Types.DOUBLE;
private static boolean isNumeric(int type) {
switch ( type ) {
case Types.SMALLINT:
case Types.TINYINT:
case Types.INTEGER:
case Types.BIGINT:
case Types.FLOAT:
case Types.REAL:
case Types.DOUBLE:
case Types.NUMERIC:
case Types.DECIMAL:
return true;
}
return false;
}
private static AllowableFunctionReturnType<?> extractArgumentType(List<SqmTypedNode<?>> arguments, int position) {