diff --git a/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc b/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc
index ae71dfbc3b..5217ba4888 100644
--- a/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc
+++ b/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc
@@ -1002,6 +1002,8 @@ Of course, we also have a number of functions for working with numeric values.
| `pi` | π | `pi` | ✗
| `sin()`, `cos()`, `tan()`, `asin()`, `acos()`, `atan()`, `atan2()`
| Basic trigonometric functions | `sin(theta)`, `cos(theta)`, `atan2(opposite, adjacent)` | ✗
+| `degrees()` | Convert radians to degrees | `degrees(x)` | ✗
+| `radians()` | Convert degrees to radians | `radians(x)` | ✗
| `least()` | Return the smallest of the given arguments | `least(x, y, z)` |✗
| `greatest()` | Return the largest of the given arguments | `greatest(x, y, z)` | ✗
|===
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java
index 31dbd5680f..767a2f7ea1 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java
@@ -377,6 +377,9 @@ public abstract class AbstractHANADialect extends Dialect {
functionFactory.inverseDistributionOrderedSetAggregates();
functionFactory.hypotheticalOrderedSetAggregates_windowEmulation();
+ functionFactory.radians_acos();
+ functionFactory.degrees_acos();
+
queryEngine.getSqmFunctionRegistry().register( "timestampadd",
new IntegralTimestampaddFunction( this, typeConfiguration ) );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
index 8adb3e5a68..a8a2488dee 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
@@ -787,6 +787,8 @@ public abstract class Dialect implements ConversionContext {
*
round(arg0, arg1)
* least(arg0, arg1, ...)
* greatest(arg0, arg1, ...)
+ * degrees(arg)
+ * radians(arg)
*
*
*
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java
index 0e50657860..9ce9bad568 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java
@@ -174,6 +174,9 @@ public class OracleDialect extends Dialect {
functionFactory.monthsBetween();
functionFactory.everyAny_minMaxCase();
+ functionFactory.radians_acos();
+ functionFactory.degrees_acos();
+
functionFactory.median();
functionFactory.stddev();
functionFactory.stddevPopSamp();
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 8737788b83..b538b84b7f 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
@@ -80,14 +80,6 @@ public class CommonFunctionFactory {
.register();
}
- public void degrees() {
- functionRegistry.namedDescriptorBuilder( "degrees" )
- .setExactArgumentCount( 1 )
- .setParameterTypes(NUMERIC)
- .setInvariantType(doubleType)
- .register();
- }
-
/**
* For databases where the first parameter is the base
*/
@@ -178,6 +170,36 @@ public class CommonFunctionFactory {
.register();
}
+ /**
+ * For Oracle, HANA
+ */
+ public void radians_acos() {
+ functionRegistry.patternDescriptorBuilder( "radians", "(?1*acos(-1)/180)" )
+ .setInvariantType(doubleType)
+ .setExactArgumentCount(1)
+ .setParameterTypes(NUMERIC)
+ .register();
+ }
+
+ public void degrees() {
+ functionRegistry.namedDescriptorBuilder( "degrees" )
+ .setExactArgumentCount( 1 )
+ .setParameterTypes(NUMERIC)
+ .setInvariantType(doubleType)
+ .register();
+ }
+
+ /**
+ * For Oracle, HANA
+ */
+ public void degrees_acos() {
+ functionRegistry.patternDescriptorBuilder( "degrees", "(?1/acos(-1)*180)" )
+ .setInvariantType(doubleType)
+ .setExactArgumentCount(1)
+ .setParameterTypes(NUMERIC)
+ .register();
+ }
+
public void sinh() {
functionRegistry.namedDescriptorBuilder( "sinh" )
.setExactArgumentCount( 1 )
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/CountFunction.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/CountFunction.java
index 5fa78abded..99c4344aa1 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/function/CountFunction.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/CountFunction.java
@@ -27,7 +27,6 @@ import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Distinct;
import org.hibernate.sql.ast.tree.expression.Expression;
-import org.hibernate.sql.ast.tree.expression.FunctionExpression;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
import org.hibernate.sql.ast.tree.expression.SqlTupleContainer;
import org.hibernate.sql.ast.tree.expression.Star;
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/StandardFunctionTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/StandardFunctionTests.java
index 2f9145f29b..27abfabc8c 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/StandardFunctionTests.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/StandardFunctionTests.java
@@ -921,6 +921,22 @@ public class StandardFunctionTests {
);
}
+ @Test
+ public void testDegreesRadians(SessionFactoryScope scope) {
+ scope.inTransaction(
+ session -> {
+ assertThat(
+ session.createQuery("select degrees(pi)", Double.class).getSingleResult(),
+ IsCloseTo.closeTo( 180.0, 1e-9 )
+ );
+ assertThat(
+ session.createQuery("select radians(180.0)", Double.class).getSingleResult(),
+ IsCloseTo.closeTo( Math.PI, 1e-9 )
+ );
+ }
+ );
+ }
+
@Test
public void testLog(SessionFactoryScope scope) {
scope.inTransaction(