remove PowerReturnTypeResolver

You can't do "exact decimal" exponentiation. For the same reason that
sqrt() is of type Double in the JPA, pow(decimal, 0.5) is also of type
Double.

Yes, yes, I know that some dbs (Postgres!) claim that the return type is
NUMERIC for NUMERIC arguments. But go on, try it: yes, the return type of
typed NUMERIC, but then it has a very suspicious number of digits. Hrrm....
17 decimal digits, now why does that specific number ring a bell?
This commit is contained in:
Gavin King 2022-01-30 19:08:58 +01:00
parent 5b5c76abfd
commit 385cba79d8
2 changed files with 6 additions and 68 deletions

View File

@ -1982,9 +1982,11 @@ public class CommonFunctionFactory {
.register(); .register();
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "power" ) queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "power" )
.setInvariantType(
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE )
)
.setExactArgumentCount( 2 ) .setExactArgumentCount( 2 )
.setParameterTypes(NUMERIC, NUMERIC) .setParameterTypes(NUMERIC, NUMERIC)
.setReturnTypeResolver( new PowerReturnTypeResolver( queryEngine.getTypeConfiguration() ) )
.register(); .register();
} }
@ -2000,9 +2002,11 @@ public class CommonFunctionFactory {
public static void power_expLn(QueryEngine queryEngine) { public static void power_expLn(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder( "power", "exp(ln(?1)*?2)" ) queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder( "power", "exp(ln(?1)*?2)" )
.setInvariantType(
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE )
)
.setExactArgumentCount( 2 ) .setExactArgumentCount( 2 )
.setParameterTypes(NUMERIC, NUMERIC) .setParameterTypes(NUMERIC, NUMERIC)
.setReturnTypeResolver( new PowerReturnTypeResolver( queryEngine.getTypeConfiguration() ) )
.register(); .register();
} }

View File

@ -1,66 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.dialect.function;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.List;
import java.util.function.Supplier;
import static org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.extractArgumentJdbcMapping;
import static org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.extractArgumentValuedMapping;
/**
* @author Christian Beikov
*/
class PowerReturnTypeResolver implements FunctionReturnTypeResolver {
private final BasicType<Double> doubleType;
PowerReturnTypeResolver(TypeConfiguration typeConfiguration) {
this.doubleType = typeConfiguration.getBasicTypeRegistry().resolve(StandardBasicTypes.DOUBLE);
}
@Override
public ReturnableType<?> resolveFunctionReturnType(
ReturnableType<?> impliedType,
List<? extends SqmTypedNode<?>> arguments,
TypeConfiguration typeConfiguration) {
final JdbcMapping baseType = extractArgumentJdbcMapping( typeConfiguration, arguments, 1 );
final JdbcMapping powerType = extractArgumentJdbcMapping( typeConfiguration, arguments, 2 );
if ( baseType.getJdbcType().isDecimal() ) {
return (ReturnableType<?>) arguments.get(0).getNodeType();
}
else if (powerType.getJdbcType().isDecimal()) {
return (ReturnableType<?>) arguments.get(1).getNodeType();
}
return typeConfiguration.getBasicTypeForJavaType(Double.class);
}
@Override
public BasicValuedMapping resolveFunctionReturnType(
Supplier<BasicValuedMapping> impliedTypeAccess, List<? extends SqlAstNode> arguments) {
final BasicValuedMapping baseMapping = extractArgumentValuedMapping( arguments,1 );
final BasicValuedMapping powerMapping = extractArgumentValuedMapping( arguments, 2 );
if ( baseMapping.getJdbcMapping().getJdbcType().isDecimal() ) {
return baseMapping;
}
else if ( powerMapping.getJdbcMapping().getJdbcType().isDecimal() ) {
return powerMapping;
}
return doubleType;
}
}