You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by do...@apache.org on 2019/07/15 03:42:12 UTC
[spark] branch master updated: [SPARK-28133][SQL] Add
acosh/asinh/atanh functions to SQL
This is an automated email from the ASF dual-hosted git repository.
dongjoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new a2f71a8 [SPARK-28133][SQL] Add acosh/asinh/atanh functions to SQL
a2f71a8 is described below
commit a2f71a8d852be166561c208fad0c9a74ae304dd3
Author: Tony Zhang <to...@uber.com>
AuthorDate: Sun Jul 14 20:41:45 2019 -0700
[SPARK-28133][SQL] Add acosh/asinh/atanh functions to SQL
## What changes were proposed in this pull request?
Adding support to hyperbolic functions like asinh\acosh\atanh in spark SQL.
Feature parity: https://www.postgresql.org/docs/12/functions-math.html#FUNCTIONS-MATH-HYP-TABLE
The followings are the diffence from PostgreSQL.
```
spark-sql> SELECT acosh(0); (PostgreSQL returns `ERROR: input is out of range`)
NaN
spark-sql> SELECT atanh(2); (PostgreSQL returns `ERROR: input is out of range`)
NaN
```
Teradata has similar behavior as PostgreSQL with out of range input float values - It outputs **Invalid Input: numeric value within range only.**
These newly added asinh/acosh/atanh handles special input(NaN, +-Infinity) in the same way as existing cos/sin/tan/acos/asin/atan in spark. For which input value range is not (-∞, ∞)):
out of range float values: Spark returns NaN and PostgreSQL shows input is out of range
NaN: Spark returns NaN, PostgreSQL also returns NaN
Infinity: Spark return NaN, PostgreSQL shows input is out of range
## How was this patch tested?
```
spark.sql("select asinh(xx)")
spark.sql("select acosh(xx)")
spark.sql("select atanh(xx)")
./build/sbt "testOnly org.apache.spark.sql.MathFunctionsSuite"
./build/sbt "testOnly org.apache.spark.sql.catalyst.expressions.MathExpressionsSuite"
```
Closes #25041 from Tonix517/SPARK-28133.
Authored-by: Tony Zhang <to...@uber.com>
Signed-off-by: Dongjoon Hyun <dh...@apple.com>
---
.../sql/catalyst/analysis/FunctionRegistry.scala | 3 +
.../sql/catalyst/expressions/mathExpressions.scala | 71 ++++++++++++++++++++++
.../expressions/MathExpressionsSuite.scala | 32 ++++++++++
3 files changed, 106 insertions(+)
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
index 9fe9567..c72400a 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
@@ -222,9 +222,12 @@ object FunctionRegistry {
// math functions
expression[Acos]("acos"),
+ expression[Acosh]("acosh"),
expression[Asin]("asin"),
+ expression[Asinh]("asinh"),
expression[Atan]("atan"),
expression[Atan2]("atan2"),
+ expression[Atanh]("atanh"),
expression[Bin]("bin"),
expression[BRound]("bround"),
expression[Cbrt]("cbrt"),
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala
index bdeb9ed..e873f8e 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala
@@ -287,6 +287,29 @@ case class Cos(child: Expression) extends UnaryMathExpression(math.cos, "COS")
""")
case class Cosh(child: Expression) extends UnaryMathExpression(math.cosh, "COSH")
+@ExpressionDescription(
+ usage = """
+ _FUNC_(expr) - Returns inverse hyperbolic cosine of `expr`.
+ """,
+ arguments = """
+ Arguments:
+ * expr - hyperbolic angle
+ """,
+ examples = """
+ Examples:
+ > SELECT _FUNC_(1);
+ 0.0
+ > SELECT _FUNC_(0);
+ NaN
+ """,
+ since = "3.0.0")
+case class Acosh(child: Expression)
+ extends UnaryMathExpression((x: Double) => math.log(x + math.sqrt(x * x - 1.0)), "ACOSH") {
+ override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
+ defineCodeGen(ctx, ev, c => s"java.lang.Math.log($c + java.lang.Math.sqrt($c * $c - 1.0))")
+ }
+}
+
/**
* Convert a num from one base to another
*
@@ -558,6 +581,31 @@ case class Sin(child: Expression) extends UnaryMathExpression(math.sin, "SIN")
case class Sinh(child: Expression) extends UnaryMathExpression(math.sinh, "SINH")
@ExpressionDescription(
+ usage = """
+ _FUNC_(expr) - Returns inverse hyperbolic sine of `expr`.
+ """,
+ arguments = """
+ Arguments:
+ * expr - hyperbolic angle
+ """,
+ examples = """
+ Examples:
+ > SELECT _FUNC_(0);
+ 0.0
+ """,
+ since = "3.0.0")
+case class Asinh(child: Expression)
+ extends UnaryMathExpression((x: Double) => x match {
+ case Double.NegativeInfinity => Double.NegativeInfinity
+ case _ => math.log(x + math.sqrt(x * x + 1.0)) }, "ASINH") {
+ override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
+ defineCodeGen(ctx, ev, c =>
+ s"$c == Double.NEGATIVE_INFINITY ? Double.NEGATIVE_INFINITY : " +
+ s"java.lang.Math.log($c + java.lang.Math.sqrt($c * $c + 1.0))")
+ }
+}
+
+@ExpressionDescription(
usage = "_FUNC_(expr) - Returns the square root of `expr`.",
examples = """
Examples:
@@ -618,6 +666,29 @@ case class Cot(child: Expression)
case class Tanh(child: Expression) extends UnaryMathExpression(math.tanh, "TANH")
@ExpressionDescription(
+ usage = """
+ _FUNC_(expr) - Returns inverse hyperbolic tangent of `expr`.
+ """,
+ arguments = """
+ Arguments:
+ * expr - hyperbolic angle
+ """,
+ examples = """
+ Examples:
+ > SELECT _FUNC_(0);
+ 0.0
+ > SELECT _FUNC_(2);
+ NaN
+ """,
+ since = "3.0.0")
+case class Atanh(child: Expression)
+ extends UnaryMathExpression((x: Double) => 0.5 * math.log((1.0 + x) / (1.0 - x)), "ATANH") {
+ override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
+ defineCodeGen(ctx, ev, c => s"0.5 * java.lang.Math.log((1.0 + $c)/(1.0 - $c))")
+ }
+}
+
+@ExpressionDescription(
usage = "_FUNC_(expr) - Converts radians to degrees.",
arguments = """
Arguments:
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/MathExpressionsSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/MathExpressionsSuite.scala
index 4810557..4c048f7 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/MathExpressionsSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/MathExpressionsSuite.scala
@@ -199,6 +199,18 @@ class MathExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkConsistencyBetweenInterpretedAndCodegen(Sinh, DoubleType)
}
+ test("asinh") {
+ testUnary(Asinh, (x: Double) => math.log(x + math.sqrt(x * x + 1.0)))
+ checkConsistencyBetweenInterpretedAndCodegen(Asinh, DoubleType)
+
+ checkEvaluation(Asinh(Double.NegativeInfinity), Double.NegativeInfinity)
+
+ val nullLit = Literal.create(null, NullType)
+ val doubleNullLit = Literal.create(null, DoubleType)
+ checkEvaluation(checkDataTypeAndCast(Asinh(nullLit)), null, EmptyRow)
+ checkEvaluation(checkDataTypeAndCast(Asinh(doubleNullLit)), null, EmptyRow)
+ }
+
test("cos") {
testUnary(Cos, math.cos)
checkConsistencyBetweenInterpretedAndCodegen(Cos, DoubleType)
@@ -215,6 +227,16 @@ class MathExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkConsistencyBetweenInterpretedAndCodegen(Cosh, DoubleType)
}
+ test("acosh") {
+ testUnary(Acosh, (x: Double) => math.log(x + math.sqrt(x * x - 1.0)))
+ checkConsistencyBetweenInterpretedAndCodegen(Cosh, DoubleType)
+
+ val nullLit = Literal.create(null, NullType)
+ val doubleNullLit = Literal.create(null, DoubleType)
+ checkEvaluation(checkDataTypeAndCast(Acosh(nullLit)), null, EmptyRow)
+ checkEvaluation(checkDataTypeAndCast(Acosh(doubleNullLit)), null, EmptyRow)
+ }
+
test("tan") {
testUnary(Tan, math.tan)
checkConsistencyBetweenInterpretedAndCodegen(Tan, DoubleType)
@@ -244,6 +266,16 @@ class MathExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkConsistencyBetweenInterpretedAndCodegen(Tanh, DoubleType)
}
+ test("atanh") {
+ testUnary(Atanh, (x: Double) => 0.5 * math.log((1.0 + x) / (1.0 - x)))
+ checkConsistencyBetweenInterpretedAndCodegen(Atanh, DoubleType)
+
+ val nullLit = Literal.create(null, NullType)
+ val doubleNullLit = Literal.create(null, DoubleType)
+ checkEvaluation(checkDataTypeAndCast(Atanh(nullLit)), null, EmptyRow)
+ checkEvaluation(checkDataTypeAndCast(Atanh(doubleNullLit)), null, EmptyRow)
+ }
+
test("toDegrees") {
testUnary(ToDegrees, math.toDegrees)
checkConsistencyBetweenInterpretedAndCodegen(ToDegrees, DoubleType)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org