This is an automated email from the ASF dual-hosted git repository.
rubenql pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new af2fb7f02b [CALCITE-5608] Implement ASINH, ACOSH, ATANH functions
af2fb7f02b is described below
commit af2fb7f02b30bf853cf9f4c384fbcfeafefcebdf
Author: zoudan <[email protected]>
AuthorDate: Mon May 15 16:19:49 2023 +0800
[CALCITE-5608] Implement ASINH, ACOSH, ATANH functions
---
.../calcite/adapter/enumerable/RexImpTable.java | 6 ++
.../org/apache/calcite/runtime/SqlFunctions.java | 56 ++++++++++++++++++
.../calcite/sql/fun/SqlLibraryOperators.java | 26 ++++++++
site/_docs/reference.md | 3 +
.../org/apache/calcite/test/SqlOperatorTest.java | 69 ++++++++++++++++++++++
5 files changed, 160 insertions(+)
diff --git
a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 6bc1dd18e7..4d8e51bb15 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -112,6 +112,7 @@ import static
org.apache.calcite.linq4j.tree.ExpressionType.NotEqual;
import static org.apache.calcite.linq4j.tree.ExpressionType.Subtract;
import static org.apache.calcite.linq4j.tree.ExpressionType.UnaryPlus;
import static org.apache.calcite.sql.fun.SqlInternalOperators.THROW_UNLESS;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.ACOSH;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_AGG;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_CONCAT;
@@ -121,6 +122,8 @@ import static
org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_LENGTH;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_REPEAT;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_REVERSE;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_SIZE;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.ASINH;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.ATANH;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.BOOL_AND;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.BOOL_OR;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.CHAR;
@@ -529,9 +532,12 @@ public class RexImpTable {
map.put(RAND_INTEGER, new RandIntegerImplementor());
defineMethod(ACOS, "acos", NullPolicy.STRICT);
+ defineMethod(ACOSH, "acosh", NullPolicy.STRICT);
defineMethod(ASIN, "asin", NullPolicy.STRICT);
+ defineMethod(ASINH, "asinh", NullPolicy.STRICT);
defineMethod(ATAN, "atan", NullPolicy.STRICT);
defineMethod(ATAN2, "atan2", NullPolicy.STRICT);
+ defineMethod(ATANH, "atanh", NullPolicy.STRICT);
defineMethod(CBRT, "cbrt", NullPolicy.STRICT);
defineMethod(COS, "cos", NullPolicy.STRICT);
defineMethod(COSH, "cosh", NullPolicy.STRICT);
diff --git a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
index 1fc339fc07..d9621c5c1b 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -1854,6 +1854,20 @@ public class SqlFunctions {
return Math.acos(b0);
}
+ // ACOSH
+ /** SQL <code>ACOSH</code> operator applied to BigDecimal values. */
+ public static double acosh(BigDecimal b0) {
+ return acosh(b0.doubleValue());
+ }
+
+ /** SQL <code>ACOSH</code> operator applied to double values. */
+ public static double acosh(double b0) {
+ if (b0 < 1) {
+ throw new IllegalArgumentException("Input parameter of acosh cannot be
less than 1!");
+ }
+ return Math.log(Math.sqrt(b0 * b0 - 1.0d) + b0);
+ }
+
// ASIN
/** SQL <code>ASIN</code> operator applied to BigDecimal values. */
public static double asin(BigDecimal b0) {
@@ -1865,6 +1879,25 @@ public class SqlFunctions {
return Math.asin(b0);
}
+ // ASINH
+ /** SQL <code>ASINH</code> operator applied to BigDecimal values. */
+ public static double asinh(BigDecimal b0) {
+ return asinh(b0.doubleValue());
+ }
+
+ /** SQL <code>ASINH</code> operator applied to double values. */
+ public static double asinh(double b0) {
+ final double sign;
+ // check the sign bit of the raw representation to handle -0.
+ if (Double.doubleToRawLongBits(b0) < 0) {
+ b0 = Math.abs(b0);
+ sign = -1.0d;
+ } else {
+ sign = 1.0d;
+ }
+ return sign * Math.log(Math.sqrt(b0 * b0 + 1.0d) + b0);
+ }
+
// ATAN
/** SQL <code>ATAN</code> operator applied to BigDecimal values. */
public static double atan(BigDecimal b0) {
@@ -1897,6 +1930,29 @@ public class SqlFunctions {
return Math.atan2(b0, b1);
}
+ // ATANH
+ /** SQL <code>ATANH</code> operator applied to BigDecimal values. */
+ public static double atanh(BigDecimal b) {
+ return atanh(b.doubleValue());
+ }
+
+ /** SQL <code>ATANH</code> operator applied to double values. */
+ public static double atanh(double b) {
+ if (Math.abs(b) >= 1) {
+ throw new IllegalArgumentException("Input parameter of atanh cannot be
out of the "
+ + "range (-1, 1)!");
+ }
+ final double mult;
+ // check the sign bit of the raw representation to handle -0.
+ if (Double.doubleToRawLongBits(b) < 0) {
+ b = Math.abs(b);
+ mult = -0.5d;
+ } else {
+ mult = 0.5d;
+ }
+ return mult * Math.log((1.0d + b) / (1.0d - b));
+ }
+
// CBRT
/** SQL <code>CBRT</code> operator applied to BigDecimal values. */
public static double cbrt(BigDecimal b) {
diff --git
a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
index a1952900eb..01c16396c3 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
@@ -1277,6 +1277,32 @@ public abstract class SqlLibraryOperators {
OperandTypes.NUMERIC,
SqlFunctionCategory.NUMERIC);
+ /** The {@code ACOSH(numeric)} function; returns the inverse hyperbolic
cosine
+ * of {@code value}. */
+ @LibraryOperator(libraries = {ALL})
+ public static final SqlFunction ACOSH =
+ SqlBasicFunction.create("ACOSH",
+ ReturnTypes.DOUBLE_NULLABLE,
+ OperandTypes.NUMERIC,
+ SqlFunctionCategory.NUMERIC);
+
+ /** The {@code ASINH(numeric)} function; returns the inverse hyperbolic sine
of {@code value}. */
+ @LibraryOperator(libraries = {ALL})
+ public static final SqlFunction ASINH =
+ SqlBasicFunction.create("ASINH",
+ ReturnTypes.DOUBLE_NULLABLE,
+ OperandTypes.NUMERIC,
+ SqlFunctionCategory.NUMERIC);
+
+ /** The {@code ATANH(numeric)} function; returns the inverse hyperbolic
tangent
+ * of {@code value}. */
+ @LibraryOperator(libraries = {ALL})
+ public static final SqlFunction ATANH =
+ SqlBasicFunction.create("ATANH",
+ ReturnTypes.DOUBLE_NULLABLE,
+ OperandTypes.NUMERIC,
+ SqlFunctionCategory.NUMERIC);
+
/** The "COTH(value)" function; returns the hyperbolic secant
* of {@code value}. */
@LibraryOperator(libraries = {ALL})
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 077ecb75c3..7baa3d64df 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -2650,6 +2650,7 @@ BigQuery's type system uses confusingly different names
for types and functions:
|:- |:-----------------------------------------------|:-----------
| p | expr :: type | Casts *expr* to *type*
| m | expr1 <=> expr2 | Whether two values are
equal, treating null values as the same, and it's similar to `IS NOT DISTINCT
FROM`
+| * | ACOSH(numeric) | Returns the inverse
hyperbolic cosine of *numeric*
| s | ARRAY(expr [, expr ]*) | Construct an array in
Apache Spark
| b | ARRAY_CONCAT(array [, array ]*) | Concatenates one or
more arrays. If any input argument is `NULL` the function returns `NULL`
| s | ARRAY_DISTINCT(array) | Returns unique elements
of *array*. Keeps ordering of elements.
@@ -2657,6 +2658,8 @@ BigQuery's type system uses confusingly different names
for types and functions:
| s | ARRAY_REPEAT(element, count) | Returns the array
containing element count times.
| b | ARRAY_REVERSE(array) | Reverses elements of
*array*
| s | ARRAY_SIZE(array) | Synonym for
`CARDINALITY`
+| * | ASINH(numeric) | Returns the inverse
hyperbolic sine of *numeric*
+| * | ATANH(numeric) | Returns the inverse
hyperbolic tangent of *numeric*
| m s | CHAR(integer) | Returns the character
whose ASCII code is *integer* % 256, or null if *integer* < 0
| b o p | CHR(integer) | Returns the character
whose UTF-8 code is *integer*
| o | CONCAT(string, string) | Concatenates two strings
diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
index 57585050b4..bf9412efb6 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -5587,6 +5587,75 @@ public class SqlOperatorTest {
f.checkNull("atan2(1, cast(null as double))");
}
+ @Test void testAcoshFunc() {
+ final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.ACOSH);
+ f0.checkFails("^acosh(1)^",
+ "No match found for function signature ACOSH\\(<NUMERIC>\\)",
+ false);
+ final Consumer<SqlOperatorFixture> consumer = f -> {
+ f.checkType("acosh(1)", "DOUBLE NOT NULL");
+ f.checkType("acosh(cast(1 as Decimal))", "DOUBLE NOT NULL");
+ f.checkType("acosh(case when false then 1 else null end)", "DOUBLE");
+ f.checkType("acosh('abc')", "DOUBLE NOT NULL");
+ f.checkScalarApprox("acosh(1)", "DOUBLE NOT NULL",
+ isWithin(0d, 0.0001d));
+ f.checkScalarApprox("acosh(cast(10 as decimal))", "DOUBLE NOT NULL",
+ isWithin(2.9932d, 0.0001d));
+ f.checkNull("acosh(cast(null as integer))");
+ f.checkNull("acosh(cast(null as double))");
+ f.checkFails("acosh(0.1)",
+ "Input parameter of acosh cannot be less than 1!",
+ true);
+ };
+ f0.forEachLibrary(list(SqlLibrary.ALL), consumer);
+ }
+
+ @Test void testAsinhFunc() {
+ final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.ASINH);
+ f0.checkFails("^asinh(1)^",
+ "No match found for function signature ASINH\\(<NUMERIC>\\)",
+ false);
+ final Consumer<SqlOperatorFixture> consumer = f -> {
+ f.checkType("asinh(1)", "DOUBLE NOT NULL");
+ f.checkType("asinh(cast(1 as Decimal))", "DOUBLE NOT NULL");
+ f.checkType("asinh(case when false then 1 else null end)", "DOUBLE");
+ f.checkType("asinh('abc')", "DOUBLE NOT NULL");
+ f.checkScalarApprox("asinh(-2.5)", "DOUBLE NOT NULL",
+ isWithin(-1.6472d, 0.0001d));
+ f.checkScalarApprox("asinh(cast(10 as decimal))", "DOUBLE NOT NULL",
+ isWithin(2.9982, 0.0001d));
+ f.checkNull("asinh(cast(null as integer))");
+ f.checkNull("asinh(cast(null as double))");
+ };
+ f0.forEachLibrary(list(SqlLibrary.ALL), consumer);
+ }
+
+ @Test void testAtanhFunc() {
+ final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.ATANH);
+ f0.checkFails("^atanh(1)^",
+ "No match found for function signature ATANH\\(<NUMERIC>\\)",
+ false);
+ final Consumer<SqlOperatorFixture> consumer = f -> {
+ f.checkType("atanh(0.1)", "DOUBLE NOT NULL");
+ f.checkType("atanh(cast(0 as Decimal))", "DOUBLE NOT NULL");
+ f.checkType("atanh(case when false then 0 else null end)", "DOUBLE");
+ f.checkType("atanh('abc')", "DOUBLE NOT NULL");
+ f.checkScalarApprox("atanh(0.76159416)", "DOUBLE NOT NULL",
+ isWithin(1d, 0.0001d));
+ f.checkScalarApprox("atanh(cast(-0.1 as decimal))", "DOUBLE NOT NULL",
+ isWithin(-0.1003d, 0.0001d));
+ f.checkNull("atanh(cast(null as integer))");
+ f.checkNull("atanh(cast(null as double))");
+ f.checkFails("atanh(1)",
+ "Input parameter of atanh cannot be out of the range \\(-1, 1\\)!",
+ true);
+ f.checkFails("atanh(-1)",
+ "Input parameter of atanh cannot be out of the range \\(-1, 1\\)!",
+ true);
+ };
+ f0.forEachLibrary(list(SqlLibrary.ALL), consumer);
+ }
+
@Test void testCbrtFunc() {
final SqlOperatorFixture f = fixture();
f.setFor(SqlStdOperatorTable.CBRT, VmName.EXPAND);