Обсуждение: Regression tests on intel for 6.5.2

Поиск
Список
Период
Сортировка

Regression tests on intel for 6.5.2

От
Lamar Owen
Дата:
In the course of building and testing the rpm's for 6.5.2, unexpected
results were found in the regression testing.  I am curious as to what
the results for 'float8' mean (geometry also failed, but it's obvious as
to why):

> *** expected/float8.out Sat Jan 23 19:12:59 1999
> --- results/float8.out  Mon Sep 27 11:01:13 1999
> ***************
> *** 189,201 ****
>   QUERY: SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
>   ERROR:  Bad float8 input format -- overflow
>   QUERY: SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
> ! ERROR:  pow() result is out of range
>   QUERY: SELECT '' AS bad, (; (f.f1)) from FLOAT8_TBL f where f.f1 = '0.0' ;
>   ERROR:  can't take log of zero
>   QUERY: SELECT '' AS bad, (; (f.f1)) from FLOAT8_TBL f where f.f1 < '0.0' ;
>   ERROR:  can't take log of a negative number
>   QUERY: SELECT '' AS bad, : (f.f1) from FLOAT8_TBL f;
> ! ERROR:  exp() result is out of range
>   QUERY: SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
>   ERROR:  float8div: divide by zero error
>   QUERY: SELECT '' AS five, FLOAT8_TBL.*;
> --- 189,217 ----
>   QUERY: SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
>   ERROR:  Bad float8 input format -- overflow
>   QUERY: SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
> ! bad|?column?
> ! ---+--------
> !    |0       
> !    |NaN     
> !    |NaN     
> !    |NaN     
> !    |NaN     
> ! (5 rows)
> ! 
>   QUERY: SELECT '' AS bad, (; (f.f1)) from FLOAT8_TBL f where f.f1 = '0.0' ;
>   ERROR:  can't take log of zero
>   QUERY: SELECT '' AS bad, (; (f.f1)) from FLOAT8_TBL f where f.f1 < '0.0' ;
>   ERROR:  can't take log of a negative number
>   QUERY: SELECT '' AS bad, : (f.f1) from FLOAT8_TBL f;
> ! bad|            ?column?
> ! ---+--------------------
> !    |                   1
> !    |7.39912306090513e-16
> !    |                   0
> !    |                   0
> !    |                   1
> ! (5 rows)
> ! 
>   QUERY: SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
>   ERROR:  float8div: divide by zero error
>   QUERY: SELECT '' AS five, FLOAT8_TBL.*;
> 
> ----------------------

TIA

Lamar Owen
WGCR Internet Radio


Re: [HACKERS] Regression tests on intel for 6.5.2

От
Tom Lane
Дата:
Lamar Owen <lamar.owen@wgcr.org> writes:
> In the course of building and testing the rpm's for 6.5.2, unexpected
> results were found in the regression testing.  I am curious as to what
> the results for 'float8' mean (geometry also failed, but it's obvious as
> to why):

I saw similar results with older Postgres releases on HPUX.  The problem
is failure to detect an invalid result from the exp() library function.
Unfortunately there's not complete uniformity about how to test that
on different platforms.

What's currently in dexp() in backend/utils/adt/float.c is

#ifndef finite
    errno = 0;
#endif
    *result = (float64data) exp(tmp);
#ifndef finite
    if (errno == ERANGE)
#else
    /* infinity implies overflow, zero implies underflow */
    if (!finite(*result) || *result == 0.0)
#endif
        elog(ERROR, "exp() result is out of range");

which is evidently doing the wrong thing on your platform.  What does
your man page for exp() say about error return conventions?

I suspect the assumption that finite() is always implemented as a macro
if it's present at all is the weak spot ... or it might be that your
math lib returns some other error code like EDOM ...

            regards, tom lane


Re: [HACKERS] Regression tests on intel for 6.5.2

От
Lamar Owen
Дата:
On Mon, 27 Sep 1999, Tom Lane wrote:
> which is evidently doing the wrong thing on your platform.  What does
> your man page for exp() say about error return conventions?

Platform is Intel Linux -- specifically:
RedHat Linux 6.0/Intel (glibc 2.1.1):

Man page for exp(3)...
-------------------
The log() and log10() functions can return the following errors:

EDOM
The argument x is negative.

ERANGE The argument x is zero. The log of zero is not defined.

The pow() function can return the following error:

EDOM
The argument x is negative and y is not an integral value. This would result in a complex number.
-------------------------------

> I suspect the assumption that finite() is always implemented as a macro
> if it's present at all is the weak spot ... or it might be that your
> math lib returns some other error code like EDOM ...

Man page finite(3)
-------------------------------
The finite() function returns a non-zero value if value is neither infinite nor a
�not-a-number� (NaN) value, and 0 otherwise.
-------------------------------

Seems that there was a table in those regression test results populated by
NaN....

-----------------------------------------------------------------------------
Lamar Owen
WGCR Internet Radio
1 Peter 4:11


Re: [HACKERS] Regression tests on intel for 6.5.2

От
Christof Petig
Дата:
Lamar Owen wrote:

> On Mon, 27 Sep 1999, Tom Lane wrote:
> > which is evidently doing the wrong thing on your platform.  What does
> > your man page for exp() say about error return conventions?
>

I checked it twice, I can't find any error in the current sources. I even wrote a test program:
#include <math.h>
#include <stdio.h>
#include <errno.h>

int main()
{  double e;  errno=0;  e=pow(100,200);  if (errno) perror("pow");  if (!finite(e)) puts("!finite\n");  else
printf("%f\n",e);
}

Output:
pow: Numerical result out of range
!finite

So both methods seem to work. (finite is a function on glibc-2.1 systems)

Perhaps (strange thoughts come in to my mind ...) the compiler optimizes the function call into a
machine instruction ...
/tmp> cc -O2 -o test test.c -lm
/tmp> ./test
!finite

Looks like this is the case. So (I use gcc-2.95) what to do? Complain about a compiler/library bug
(doesn't set errno)? I would propose another autoconf test. (I could easily do it.)
Christof

PS: I found the offending inline routines in /usr/include/bits/mathinline.h




Re: [HACKERS] Regression tests on intel for 6.5.2

От
Tom Lane
Дата:
Christof Petig <christof.petig@wtal.de> writes:
> Perhaps (strange thoughts come in to my mind ...) the compiler
> optimizes the function call into a machine instruction ...
> /tmp> cc -O2 -o test test.c -lm
> /tmp> ./test
> !finite

> Looks like this is the case.

Bingo!  I think you've got it.

> I would propose another autoconf test. (I could easily do it.)

Yes, we should not be assuming that finite() is a macro, which is what
that #ifdef coding does.  We need a HAVE_FINITE configuration test.
If you have time to prepare the diffs it'd be great.
        regards, tom lane


Re: [HACKERS] Regression tests on intel for 6.5.2

От
Thomas Lockhart
Дата:
> > > which is evidently doing the wrong thing on your platform.  What does
> > > your man page for exp() say about error return conventions?
> I checked it twice, I can't find any error in the current sources. I even wrote a test 
> program...
> So both methods seem to work. (finite is a function on glibc-2.1 systems)

And that is the problem. I didn't have enough platforms to test on, so
when I improved the code I did so in a way that I would get a better
result on at least my platform (probably RH4.2 or earlier) without
breaking the behavior on other platforms.

So, I test locally for finite() being defined as a macro! But on newer
glibc systems it is a real function, so you are seeing the old
behavior.

A better thing to do would be to define HAVE_FINITE, and to have a
./configure test for it. That should be easy enough; do you have time
to look at it? Then code like

#ifndef finite   if (errno == ERANGE)
#else   /* infinity implies overflow, zero implies underflow */   if (!finite(*result) || *result == 0.0)
#endif

Could become

...
#if HAVE_FINITE
...
                       - Thomas

-- 
Thomas Lockhart                lockhart@alumni.caltech.edu
South Pasadena, California


Re: [HACKERS] Regression tests on intel for 6.5.2

От
Christof Petig
Дата:
Tom Lane wrote:

> Yes, we should not be assuming that finite() is a macro, which is what
> that #ifdef coding does.  We need a HAVE_FINITE configuration test.
> If you have time to prepare the diffs it'd be great.

Here they are
  Christof

diff -ru /home/christof/pgsql-cvs/pgsql/src/backend/utils/adt/float.c pgsql/src/backend/utils/adt/float.c
--- /home/christof/pgsql-cvs/pgsql/src/backend/utils/adt/float.c    Mon Sep 27 10:07:29 1999
+++ pgsql/src/backend/utils/adt/float.c    Fri Oct  1 11:49:32 1999
@@ -1157,11 +1157,11 @@

     tmp1 = *arg1;
     tmp2 = *arg2;
-#ifndef finite
+#ifndef HAVE_FINITE
     errno = 0;
 #endif
     *result = (float64data) pow(tmp1, tmp2);
-#ifndef finite
+#ifndef HAVE_FINITE
     if (errno != 0)                /* on some machines both EDOM & ERANGE can
                                  * occur */
 #else
@@ -1189,11 +1189,11 @@
     result = (float64) palloc(sizeof(float64data));

     tmp = *arg1;
-#ifndef finite
+#ifndef HAVE_FINITE
     errno = 0;
 #endif
     *result = (float64data) exp(tmp);
-#ifndef finite
+#ifndef HAVE_FINITE
     if (errno == ERANGE)
 #else
     /* infinity implies overflow, zero implies underflow */
diff -ru /home/christof/pgsql-cvs/pgsql/src/configure.in pgsql/src/configure.in
--- /home/christof/pgsql-cvs/pgsql/src/configure.in    Mon Sep 13 08:44:37 1999
+++ pgsql/src/configure.in    Fri Oct  1 11:39:25 1999
@@ -769,6 +769,12 @@
           AC_DEFINE(HAVE_RINT),
           AC_CHECK_LIB(m, rint, AC_DEFINE(HAVE_RINT), , $HPUXMATHLIB))

+AC_MSG_CHECKING(for finite() macro or function)
+AC_TRY_LINK([#include <math.h>],
+    [int dummy=finite(1.0);],
+    [AC_DEFINE(HAVE_FINITE) AC_MSG_RESULT(yes)],
+    AC_MSG_RESULT(no))
+
 dnl Check to see if we have a working 64-bit integer type.
 dnl This breaks down into two steps:
 dnl (1) figure out if the compiler has a 64-bit int type with working
diff -ru /home/christof/pgsql-cvs/pgsql/src/include/config.h.in pgsql/src/include/config.h.in
--- /home/christof/pgsql-cvs/pgsql/src/include/config.h.in    Mon Sep 13 08:44:38 1999
+++ pgsql/src/include/config.h.in    Fri Oct  1 11:46:23 1999
@@ -359,6 +359,9 @@
 /* Set to 1 if you have rint() */
 #undef HAVE_RINT

+/* Set to 1 if you have finite() */
+#undef HAVE_FINITE
+
 /* Set to 1 if you have memmove() */
 #undef HAVE_MEMMOVE


Re: [HACKERS] Regression tests on intel for 6.5.2

От
Tom Lane
Дата:
Christof Petig <christof.petig@wtal.de> writes:
>> Yes, we should not be assuming that finite() is a macro, which is what
>> that #ifdef coding does.  We need a HAVE_FINITE configuration test.
>> If you have time to prepare the diffs it'd be great.

> Here they are

Checked, applied to current.  Thanks.
        regards, tom lane