diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java index ec9bc2c70a..979103fb78 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java @@ -42,6 +42,7 @@ import org.hibernate.dialect.SpannerDialect; import org.hibernate.dialect.TimeZoneSupport; import org.hibernate.dialect.function.CommonFunctionFactory; import org.hibernate.dialect.function.FormatFunction; +import org.hibernate.dialect.function.PostgreSQLTruncRoundFunction; import org.hibernate.dialect.identity.CockroachDBIdentityColumnSupport; import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.dialect.pagination.LimitHandler; @@ -383,9 +384,9 @@ public class CockroachLegacyDialect extends Dialect { functionFactory.degrees(); functionFactory.radians(); functionFactory.pi(); - functionFactory.trunc(); //TODO: emulate second arg functionFactory.log(); functionFactory.log10_log(); + functionFactory.round(); functionFactory.bitandorxornot_operator(); functionFactory.bitAndOr(); @@ -407,6 +408,11 @@ public class CockroachLegacyDialect extends Dialect { functionFactory.listagg_stringAgg( "string" ); functionFactory.inverseDistributionOrderedSetAggregates(); functionFactory.hypotheticalOrderedSetAggregates_windowEmulation(); + + functionContributions.getFunctionRegistry().register( + "trunc", new PostgreSQLTruncRoundFunction( "trunc", getVersion().isSameOrAfter( 22, 2 ) ) + ); + functionContributions.getFunctionRegistry().registerAlternateKey( "truncate", "trunc" ); } @Override diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java index 4edddcadfa..57cbfbdebb 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java @@ -44,6 +44,7 @@ import org.hibernate.dialect.aggregate.AggregateSupport; import org.hibernate.dialect.aggregate.PostgreSQLAggregateSupport; import org.hibernate.dialect.function.CommonFunctionFactory; import org.hibernate.dialect.function.PostgreSQLMinMaxFunction; +import org.hibernate.dialect.function.PostgreSQLTruncRoundFunction; import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.dialect.identity.PostgreSQLIdentityColumnSupport; import org.hibernate.dialect.pagination.LimitHandler; @@ -605,6 +606,14 @@ public class PostgreSQLLegacyDialect extends Dialect { functionContributions.getFunctionRegistry().register( "min", new PostgreSQLMinMaxFunction( "min" ) ); functionContributions.getFunctionRegistry().register( "max", new PostgreSQLMinMaxFunction( "max" ) ); } + + functionContributions.getFunctionRegistry().register( + "round", new PostgreSQLTruncRoundFunction( "round", true ) + ); + functionContributions.getFunctionRegistry().register( + "trunc", new PostgreSQLTruncRoundFunction( "trunc", true ) + ); + functionContributions.getFunctionRegistry().registerAlternateKey( "truncate", "trunc" ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java index df128aec12..d8afd9dafe 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java @@ -27,6 +27,7 @@ import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; import org.hibernate.dialect.function.CommonFunctionFactory; import org.hibernate.dialect.function.FormatFunction; +import org.hibernate.dialect.function.PostgreSQLTruncRoundFunction; import org.hibernate.dialect.identity.CockroachDBIdentityColumnSupport; import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.dialect.pagination.LimitHandler; @@ -389,9 +390,9 @@ public class CockroachDialect extends Dialect { functionFactory.degrees(); functionFactory.radians(); functionFactory.pi(); - functionFactory.trunc(); //TODO: emulate second arg functionFactory.log(); functionFactory.log10_log(); + functionFactory.round(); functionFactory.bitandorxornot_operator(); functionFactory.bitAndOr(); @@ -413,6 +414,11 @@ public class CockroachDialect extends Dialect { functionFactory.listagg_stringAgg( "string" ); functionFactory.inverseDistributionOrderedSetAggregates(); functionFactory.hypotheticalOrderedSetAggregates_windowEmulation(); + + functionContributions.getFunctionRegistry().register( + "trunc", new PostgreSQLTruncRoundFunction( "trunc", getVersion().isSameOrAfter( 22, 2 ) ) + ); + functionContributions.getFunctionRegistry().registerAlternateKey( "truncate", "trunc" ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java index 1b1d769ef0..552972101c 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java @@ -28,6 +28,7 @@ import org.hibernate.boot.model.TypeContributions; import org.hibernate.dialect.aggregate.AggregateSupport; import org.hibernate.dialect.aggregate.PostgreSQLAggregateSupport; import org.hibernate.dialect.function.CommonFunctionFactory; +import org.hibernate.dialect.function.PostgreSQLTruncRoundFunction; import org.hibernate.dialect.function.PostgreSQLMinMaxFunction; import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.dialect.identity.PostgreSQLIdentityColumnSupport; @@ -523,8 +524,6 @@ public class PostgreSQLDialect extends Dialect { CommonFunctionFactory functionFactory = new CommonFunctionFactory(functionContributions); - functionFactory.round_roundFloor(); //Postgres round(x,n) does not accept double - functionFactory.trunc_truncFloor(); functionFactory.cot(); functionFactory.radians(); functionFactory.degrees(); @@ -588,6 +587,14 @@ public class PostgreSQLDialect extends Dialect { functionContributions.getFunctionRegistry().register( "min", new PostgreSQLMinMaxFunction( "min" ) ); functionContributions.getFunctionRegistry().register( "max", new PostgreSQLMinMaxFunction( "max" ) ); } + + functionContributions.getFunctionRegistry().register( + "round", new PostgreSQLTruncRoundFunction( "round", true ) + ); + functionContributions.getFunctionRegistry().register( + "trunc", new PostgreSQLTruncRoundFunction( "trunc", true ) + ); + functionContributions.getFunctionRegistry().registerAlternateKey( "truncate", "trunc" ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/PostgreSQLTruncRoundFunction.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/PostgreSQLTruncRoundFunction.java new file mode 100644 index 0000000000..2b3df38145 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/PostgreSQLTruncRoundFunction.java @@ -0,0 +1,99 @@ +/* + * 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 java.util.List; + +import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor; +import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator; +import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators; +import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers; +import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers; +import org.hibernate.sql.ast.SqlAstTranslator; +import org.hibernate.sql.ast.spi.SqlAppender; +import org.hibernate.sql.ast.tree.SqlAstNode; +import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.type.descriptor.jdbc.JdbcType; + +import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER; +import static org.hibernate.query.sqm.produce.function.FunctionParameterType.NUMERIC; + +/** + * PostgreSQL only supports the two-argument {@code trunc} and {@code round} functions + * with the following signatures: + *
+ * This custom function falls back to using {@code floor} as a workaround only when necessary, + * e.g. when there are 2 arguments to the function and either: + *