Hi,
Thanks for your time and advice, Tom!
> > [ adding_log10_and_hyperbolic_functions_v1.patch ]
>
> No objection to the feature, but
>
> - Why are you using the float4-width library functions (coshf etc)
> rather than the float8-width ones (cosh etc)?
>
> Well, I guess the only reason is that I wasn't paying attention enough...
I changed for the float8-width library functions.
> - I wonder whether these library functions exist everywhere.
> If they don't, what will we do about it ... throw an error?
>
> I see that SUSv2 requires cosh() and so on, so it's quite possible
> that these do exist everywhere we care about. I'd be okay with
> throwing a patch onto the buildfarm to see, and adding an autoconf
> test only if the buildfarm is unhappy. But we should be clear on
> what we're going to do about it if that happens.
>
> I think I was too confident because of the "it works on my laptop"
syndrome... I don't know how to answer to this point.
> > 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.
>
> Not quite sure I believe that.
>
> Do you mean I should also add a regression test for the new log10 function
too ?
> Actually, what I'd counsel is that you *not* include tests of what
> these do with Inf and NaN. There is no upside to doing so, and lots
> of downside if older platforms are squirrely in their behavior, which
> is hardly unlikely (cf opossum ...)
>
I changed the regression tests for hyperbolic functions, so it doesn't test
for Inf and NaN.
You'll find enclosed the new version of the patch.
Cheers,
Lætitia
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..7712c3d5bd 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 = sinh(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 = cosh(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 = tanh(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..3f76929591 100644
--- a/src/test/regress/expected/float8.out
+++ b/src/test/regress/expected/float8.out
@@ -632,4 +632,23 @@ 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 cosh(float8 '0');
+ cosh
+------
+ 1
+(1 row)
+
+SELECT tanh(float8 '0');
+ tanh
+------
+ 0
+(1 row)
+
RESET extra_float_digits;
diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql
index 6595fd2b95..b099ae6321 100644
--- a/src/test/regress/sql/float8.sql
+++ b/src/test/regress/sql/float8.sql
@@ -232,4 +232,9 @@ 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 cosh(float8 '0');
+SELECT tanh(float8 '0');
+
RESET extra_float_digits;