From 385cba79d8ae6fcb031d2f2bc39231c31ca65aee Mon Sep 17 00:00:00 2001 From: Gavin King Date: Sun, 30 Jan 2022 19:08:58 +0100 Subject: [PATCH] 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? --- .../function/CommonFunctionFactory.java | 8 ++- .../function/PowerReturnTypeResolver.java | 66 ------------------- 2 files changed, 6 insertions(+), 68 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/dialect/function/PowerReturnTypeResolver.java diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java index eb04e14352..32150746de 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java @@ -1982,9 +1982,11 @@ public class CommonFunctionFactory { .register(); queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "power" ) + .setInvariantType( + queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE ) + ) .setExactArgumentCount( 2 ) .setParameterTypes(NUMERIC, NUMERIC) - .setReturnTypeResolver( new PowerReturnTypeResolver( queryEngine.getTypeConfiguration() ) ) .register(); } @@ -2000,9 +2002,11 @@ public class CommonFunctionFactory { public static void power_expLn(QueryEngine queryEngine) { queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder( "power", "exp(ln(?1)*?2)" ) + .setInvariantType( + queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE ) + ) .setExactArgumentCount( 2 ) .setParameterTypes(NUMERIC, NUMERIC) - .setReturnTypeResolver( new PowerReturnTypeResolver( queryEngine.getTypeConfiguration() ) ) .register(); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/PowerReturnTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/PowerReturnTypeResolver.java deleted file mode 100644 index 8bf6c160f1..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/PowerReturnTypeResolver.java +++ /dev/null @@ -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 doubleType; - - PowerReturnTypeResolver(TypeConfiguration typeConfiguration) { - this.doubleType = typeConfiguration.getBasicTypeRegistry().resolve(StandardBasicTypes.DOUBLE); - } - - @Override - public ReturnableType resolveFunctionReturnType( - ReturnableType impliedType, - List> 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 impliedTypeAccess, List 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; - } -}