Hello hackers,

In his blog post (What's new in SQL 2016)[
https://modern-sql.com/blog/2017-06/whats-new-in-sql-2016], Markus Winand
explained some of the changes added to SQL:2016. I spotted that Postgres
was behind other RDBMS on hyperbolic functions and log10 function.
The log10 function existed but under the name log(<value>).

The new functions can be called in a simple select statement :

    select log10(100);
    select sinh(0);
    select cosh(0);
    select tanh(0);

Even if Markus Winand had added hyperbolic functions in the paragraph
"Trigonometric and Logarithmic Functions", I didn't add hyperbolic function
with the trigonometric functions in the documentation, because hyperbolic
functions are not trigonometric functions.

I added regression tests for the new functions, but I didn't for log10
function, assuming that if log function worked, log10 will work too.

You'll find enclosed the first version of the patch that can build
successfully on my laptop against master. I'm open to any improvement.

Cheers,

Lætitia
-- 
*Think! Do you really need to print this email ? *
*There is no Planet B.*
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 4930ec17f6..94e3fcd4b9 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -896,6 +896,19 @@
        <entry><literal>2</literal></entry>
       </row>
 
+      <row>
+       <entry>
+        <indexterm>
+         <primary>log10</primary>
+        </indexterm>
+        <literal><function>log10(<type>dp</type> or <type>numeric</type>)</function></literal>
+       </entry>
+       <entry>(same as input)</entry>
+       <entry>base 10 logarithm</entry>
+       <entry><literal>log10(100.0)</literal></entry>
+       <entry><literal>2</literal></entry>
+      </row>
+
       <row>
        <entry><literal><function>log(<parameter>b</parameter> <type>numeric</type>,
         <parameter>x</parameter> <type>numeric</type>)</function></literal></entry>
@@ -1147,7 +1160,7 @@
   </para>
 
   <para>
-   Finally, <xref linkend="functions-math-trig-table"/> shows the
+   <xref linkend="functions-math-trig-table"/> shows the
    available trigonometric functions.  All trigonometric functions
    take arguments and return values of type <type>double
    precision</type>.  Each of the trigonometric functions comes in
@@ -1311,8 +1324,65 @@
    </para>
   </note>
 
-  </sect1>
+  <para>
+   Finally, <xref linkend="functions-math-hyp-table"/> shows the
+   available hyperbolic functions.
+  </para>
 
+  <table id="functions-math-hyp-table">
+    <title>Hyperbolic Functions</title>
+
+    <tgroup cols="5">
+     <thead>
+      <row>
+       <entry>Function</entry>
+       <entry>Return Type</entry>
+       <entry>Description</entry>
+       <entry>Example</entry>
+       <entry>Result</entry>
+      </row>
+     </thead>
+     <tbody>
+      <row>
+       <entry>
+        <indexterm>
+         <primary>sinh</primary>
+        </indexterm>
+        <literal><function>sinh(dp)</function></literal>
+       </entry>
+       <entry><type>dp</type></entry>
+       <entry>hyperbolic sine</entry>
+       <entry><literal>sinh(0)</literal></entry>
+       <entry><literal>0</literal></entry>
+      </row>
+      <row>
+       <entry>
+        <indexterm>
+         <primary>cosh</primary>
+        </indexterm>
+        <literal><function>cosh(dp)</function></literal>
+       </entry>
+       <entry><type>dp</type></entry>
+       <entry>hyperbolic cosine</entry>
+       <entry><literal>cosh(0)</literal></entry>
+       <entry><literal>1</literal></entry>
+      </row>
+      <row>
+       <entry>
+        <indexterm>
+         <primary>tanh</primary>
+        </indexterm>
+        <literal><function>tanh(dp)</function></literal>
+       </entry>
+       <entry><type>dp</type></entry>
+       <entry>hyperbolic tangent</entry>
+       <entry><literal>tanh(0)</literal></entry>
+       <entry><literal>0</literal></entry>
+      </row>
+     </tbody>
+    </tgroup>
+   </table>
+  </sect1>
 
   <sect1 id="functions-string">
    <title>String Functions and Operators</title>
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 117ded8d1d..c83eed99c6 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -2375,6 +2375,54 @@ radians(PG_FUNCTION_ARGS)
 	PG_RETURN_FLOAT8(float8_mul(arg1, RADIANS_PER_DEGREE));
 }
 
+/* ========== HYPERBOLIC FUNCTIONS ========== */
+
+/*
+ *		dsinh			- returns the hyperbolic sine of arg1
+ */
+Datum
+dsinh(PG_FUNCTION_ARGS)
+{
+	float8		arg1 = PG_GETARG_FLOAT8(0);
+	float8		result;
+
+	result = sinhf(arg1);
+
+	check_float8_val(result, isinf(arg1), true);
+	PG_RETURN_FLOAT8(result);
+}
+
+
+/*
+ *		dcosh			- returns the hyperbolic cosine of arg1
+ */
+Datum
+dcosh(PG_FUNCTION_ARGS)
+{
+	float8		arg1 = PG_GETARG_FLOAT8(0);
+	float8		result;
+
+	result = coshf(arg1);
+
+	check_float8_val(result, isinf(arg1), false);
+	PG_RETURN_FLOAT8(result);
+}
+
+/*
+ *		dtanh			- returns the hyperbolic tangent of arg1
+ */
+Datum
+dtanh(PG_FUNCTION_ARGS)
+{
+	float8		arg1 = PG_GETARG_FLOAT8(0);
+	float8		result;
+
+	errno = 0;
+	result = tanhf(arg1);
+
+	check_float8_val(result, false, true);
+	PG_RETURN_FLOAT8(result);
+}
 
 /*
  *		drandom		- returns a random number
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 3ecc2e12c3..ca6b09a13d 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -2617,6 +2617,9 @@
 { oid => '1340', descr => 'base 10 logarithm',
   proname => 'log', prorettype => 'float8', proargtypes => 'float8',
   prosrc => 'dlog10' },
+{ oid => '1364', descr => 'base 10 logarithm',
+  proname => 'log10', prorettype => 'float8', proargtypes => 'float8',
+  prosrc => 'dlog10' },
 { oid => '1341', descr => 'natural logarithm',
   proname => 'ln', prorettype => 'float8', proargtypes => 'float8',
   prosrc => 'dlog1' },
@@ -3283,6 +3286,17 @@
 { oid => '1610', descr => 'PI',
   proname => 'pi', prorettype => 'float8', proargtypes => '', prosrc => 'dpi' },
 
+{ oid => '2462', descr => 'hyperbolic sine',
+  proname => 'sinh', prorettype => 'float8', proargtypes => 'float8',
+  prosrc => 'dsinh' },
+{ oid => '2463', descr => 'hyperbolic cosine',
+  proname => 'cosh', prorettype => 'float8', proargtypes => 'float8',
+  prosrc => 'dcosh' },
+{ oid => '2464', descr => 'hyperbolic tangent',
+  proname => 'tanh', prorettype => 'float8', proargtypes => 'float8',
+  prosrc => 'dtanh' },
+
+
 { oid => '1618',
   proname => 'interval_mul', prorettype => 'interval',
   proargtypes => 'interval float8', prosrc => 'interval_mul' },
@@ -4195,6 +4209,9 @@
 { oid => '1741', descr => 'base 10 logarithm',
   proname => 'log', prolang => 'sql', prorettype => 'numeric',
   proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' },
+{ oid => '2023', descr => 'base 10 logarithm',
+  proname => 'log10', prolang => '14', prorettype => 'numeric',
+  proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' },
 { oid => '1742', descr => 'convert float4 to numeric',
   proname => 'numeric', prorettype => 'numeric', proargtypes => 'float4',
   prosrc => 'float4_numeric' },
diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out
index 75c0bf389b..4a9e0fb203 100644
--- a/src/test/regress/expected/float8.out
+++ b/src/test/regress/expected/float8.out
@@ -632,4 +632,77 @@ FROM (SELECT 10*cosd(a), 10*sind(a)
   10 |   0 |      0 | t
 (5 rows)
 
+-- hyperbolic functions
+SELECT sinh(float8 '0');
+ sinh 
+------
+    0
+(1 row)
+
+SELECT sinh(float8 'Infinity');
+   sinh   
+----------
+ Infinity
+(1 row)
+
+SELECT sinh(float8 '-Infinity');
+   sinh    
+-----------
+ -Infinity
+(1 row)
+
+SELECT sinh(float8 'NaN');
+ sinh 
+------
+  NaN
+(1 row)
+
+SELECT cosh(float8 '0');
+ cosh 
+------
+    1
+(1 row)
+
+SELECT cosh(float8 'Infinity');
+   cosh   
+----------
+ Infinity
+(1 row)
+
+SELECT cosh(float8 '-Infinity');
+   cosh   
+----------
+ Infinity
+(1 row)
+
+SELECT cosh(float8 'NaN');
+ cosh 
+------
+  NaN
+(1 row)
+
+SELECT tanh(float8 '0');
+ tanh 
+------
+    0
+(1 row)
+
+SELECT tanh(float8 'Infinity');
+ tanh 
+------
+    1
+(1 row)
+
+SELECT tanh(float8 '-Infinity');
+ tanh 
+------
+   -1
+(1 row)
+
+SELECT tanh(float8 'NaN');
+ tanh 
+------
+  NaN
+(1 row)
+
 RESET extra_float_digits;
diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql
index 6595fd2b95..56053d530d 100644
--- a/src/test/regress/sql/float8.sql
+++ b/src/test/regress/sql/float8.sql
@@ -232,4 +232,18 @@ SELECT x, y,
 FROM (SELECT 10*cosd(a), 10*sind(a)
       FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y);
 
+-- hyperbolic functions
+SELECT sinh(float8 '0');
+SELECT sinh(float8 'Infinity');
+SELECT sinh(float8 '-Infinity');
+SELECT sinh(float8 'NaN');
+SELECT cosh(float8 '0');
+SELECT cosh(float8 'Infinity');
+SELECT cosh(float8 '-Infinity');
+SELECT cosh(float8 'NaN');
+SELECT tanh(float8 '0');
+SELECT tanh(float8 'Infinity');
+SELECT tanh(float8 '-Infinity');
+SELECT tanh(float8 'NaN');
+
 RESET extra_float_digits;

Reply via email to