Tom Lane wrote:
> Bruce Momjian <[EMAIL PROTECTED]> writes:
> > OK, are you saying that there is a signal we are ignoring for
> > overflow/underflow, or that we should just silently overflow/underflow
> > and not throw an error?
>
> Silent underflow is fine with me; it's the norm in most all float
> implementations and won't surprise anyone. For overflow I'm OK with
> either returning infinity or throwing an error --- but if an error,
> it should only be about inf-out-with-non-inf-in, not comparisons to any
> artificial MAX/MIN values.
OK, I am happy to remove the MIN/MAX comparisons. Those were in the
original code.
The attached, updated patch creates a single CHECKFLOATVAL() macro that
does the overflow/underflow comparisons and throws an error. This also
reduces the isinf() calls. Should I be concerned we are now duplicating
the error text in all call sites?
Regression wording modified now that float4/float8 checks are merged. I
haven't update the platform-specific float* expected files yet, but will
on commit.
--
Bruce Momjian [EMAIL PROTECTED]
EnterpriseDB http://www.enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +
Index: src/backend/utils/adt/float.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/float.c,v
retrieving revision 1.131
diff -c -c -r1.131 float.c
*** src/backend/utils/adt/float.c 23 Dec 2006 02:13:24 -0000 1.131
--- src/backend/utils/adt/float.c 30 Dec 2006 18:19:57 -0000
***************
*** 12,59 ****
*
*-------------------------------------------------------------------------
*/
- /*----------
- * OLD COMMENTS
- * Basic float4 ops:
- * float4in, float4out, float4recv, float4send
- * float4abs, float4um, float4up
- * Basic float8 ops:
- * float8in, float8out, float8recv, float8send
- * float8abs, float8um, float8up
- * Arithmetic operators:
- * float4pl, float4mi, float4mul, float4div
- * float8pl, float8mi, float8mul, float8div
- * Comparison operators:
- * float4eq, float4ne, float4lt, float4le, float4gt, float4ge, float4cmp
- * float8eq, float8ne, float8lt, float8le, float8gt, float8ge, float8cmp
- * Conversion routines:
- * ftod, dtof, i4tod, dtoi4, i2tod, dtoi2, itof, ftoi, i2tof, ftoi2
- *
- * Random float8 ops:
- * dround, dtrunc, dsqrt, dcbrt, dpow, dexp, dlog1
- * Arithmetic operators:
- * float48pl, float48mi, float48mul, float48div
- * float84pl, float84mi, float84mul, float84div
- * Comparison operators:
- * float48eq, float48ne, float48lt, float48le, float48gt, float48ge
- * float84eq, float84ne, float84lt, float84le, float84gt, float84ge
- *
- * (You can do the arithmetic and comparison stuff using conversion
- * routines, but then you pay the overhead of invoking a separate
- * conversion function...)
- *
- * XXX GLUESOME STUFF. FIX IT! -AY '94
- *
- * Added some additional conversion routines and cleaned up
- * a bit of the existing code. Need to change the error checking
- * for calls to pow(), exp() since on some machines (my Linux box
- * included) these routines do not set errno. - tgl 97/05/10
- *----------
- */
#include "postgres.h"
#include <ctype.h>
- #include <float.h>
#include <math.h>
#include <limits.h>
/* for finite() on Solaris */
--- 12,20 ----
***************
*** 91,111 ****
#define MAXFLOATWIDTH 64
#define MAXDOUBLEWIDTH 128
! /* ========== USER I/O ROUTINES ========== */
! #define FLOAT4_MAX FLT_MAX
! #define FLOAT4_MIN FLT_MIN
! #define FLOAT8_MAX DBL_MAX
! #define FLOAT8_MIN DBL_MIN
/* Configurable GUC parameter */
int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
- static void CheckFloat4Val(double val);
- static void CheckFloat8Val(double val);
static int float4_cmp_internal(float4 a, float4 b);
static int float8_cmp_internal(float8 a, float8 b);
--- 52,81 ----
#define MAXFLOATWIDTH 64
#define MAXDOUBLEWIDTH 128
! /*
! * check to see if a float4/8 val has underflowed or overflowed
! */
! #define CHECKFLOATVAL(val, inf_is_valid, zero_is_valid) \
! do { \
! if (isinf(val) && !(inf_is_valid)) \
! ereport(ERROR, \
! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \
! errmsg("value out of range: overflow"))); \
! \
! if ((val) == 0.0 && !(zero_is_valid)) \
! ereport(ERROR, \
! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \
! errmsg("value out of range: underflow"))); \
! } while(0)
! /* ========== USER I/O ROUTINES ========== */
/* Configurable GUC parameter */
int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
static int float4_cmp_internal(float4 a, float4 b);
static int float8_cmp_internal(float8 a, float8 b);
***************
*** 205,248 ****
/*
- * check to see if a float4 val is outside of the FLOAT4_MIN,
- * FLOAT4_MAX bounds.
- *
- * raise an ereport() error if it is
- */
- static void
- CheckFloat4Val(double val)
- {
- if (fabs(val) > FLOAT4_MAX)
- ereport(ERROR,
- (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
- errmsg("type \"real\" value out of range: overflow")));
- if (val != 0.0 && fabs(val) < FLOAT4_MIN)
- ereport(ERROR,
- (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
- errmsg("type \"real\" value out of range: underflow")));
- }
-
- /*
- * check to see if a float8 val is outside of the FLOAT8_MIN,
- * FLOAT8_MAX bounds.
- *
- * raise an ereport() error if it is
- */
- static void
- CheckFloat8Val(double val)
- {
- if (fabs(val) > FLOAT8_MAX)
- ereport(ERROR,
- (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
- errmsg("type \"double precision\" value out of range: overflow")));
- if (val != 0.0 && fabs(val) < FLOAT8_MIN)
- ereport(ERROR,
- (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
- errmsg("type \"double precision\" value out of range: underflow")));
- }
-
- /*
* float4in - converts "num" to float
* restricted syntax:
* {<sp>} [+|-] {digit} [.{digit}] [<exp>]
--- 175,180 ----
***************
*** 369,376 ****
* if we get here, we have a legal double, still need to check to see if
* it's a legal float4
*/
! if (!isinf(val))
! CheckFloat4Val(val);
PG_RETURN_FLOAT4((float4) val);
}
--- 301,307 ----
* if we get here, we have a legal double, still need to check to see if
* it's a legal float4
*/
! CHECKFLOATVAL((float4) val, isinf(val), val == 0);
PG_RETURN_FLOAT4((float4) val);
}
***************
*** 558,565 ****
errmsg("invalid input syntax for type double precision: \"%s\"",
orig_num)));
! if (!isinf(val))
! CheckFloat8Val(val);
PG_RETURN_FLOAT8(val);
}
--- 489,495 ----
errmsg("invalid input syntax for type double precision: \"%s\"",
orig_num)));
! CHECKFLOATVAL(val, true, true);
PG_RETURN_FLOAT8(val);
}
***************
*** 652,659 ****
float4um(PG_FUNCTION_ARGS)
{
float4 arg1 = PG_GETARG_FLOAT4(0);
! PG_RETURN_FLOAT4((float4) -arg1);
}
Datum
--- 582,593 ----
float4um(PG_FUNCTION_ARGS)
{
float4 arg1 = PG_GETARG_FLOAT4(0);
+ float4 result;
+
+ result = ((arg1 != 0) ? -(arg1) : arg1);
! CHECKFLOATVAL(result, isinf(arg1), true);
! PG_RETURN_FLOAT4(result);
}
Datum
***************
*** 705,716 ****
float8abs(PG_FUNCTION_ARGS)
{
float8 arg1 = PG_GETARG_FLOAT8(0);
- float8 result;
-
- result = fabs(arg1);
! CheckFloat8Val(result);
! PG_RETURN_FLOAT8(result);
}
--- 639,646 ----
float8abs(PG_FUNCTION_ARGS)
{
float8 arg1 = PG_GETARG_FLOAT8(0);
! PG_RETURN_FLOAT8(fabs(arg1));
}
***************
*** 725,731 ****
result = ((arg1 != 0) ? -(arg1) : arg1);
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 655,661 ----
result = ((arg1 != 0) ? -(arg1) : arg1);
! CHECKFLOATVAL(result, isinf(arg1), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 783,793 ****
{
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 arg2 = PG_GETARG_FLOAT4(1);
! double result;
result = arg1 + arg2;
! CheckFloat4Val(result);
! PG_RETURN_FLOAT4((float4) result);
}
Datum
--- 713,723 ----
{
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 arg2 = PG_GETARG_FLOAT4(1);
! float4 result;
result = arg1 + arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
! PG_RETURN_FLOAT4(result);
}
Datum
***************
*** 795,805 ****
{
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 arg2 = PG_GETARG_FLOAT4(1);
! double result;
result = arg1 - arg2;
! CheckFloat4Val(result);
! PG_RETURN_FLOAT4((float4) result);
}
Datum
--- 725,735 ----
{
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 arg2 = PG_GETARG_FLOAT4(1);
! float4 result;
result = arg1 - arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
! PG_RETURN_FLOAT4(result);
}
Datum
***************
*** 807,817 ****
{
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 arg2 = PG_GETARG_FLOAT4(1);
! double result;
result = arg1 * arg2;
! CheckFloat4Val(result);
! PG_RETURN_FLOAT4((float4) result);
}
Datum
--- 737,748 ----
{
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 arg2 = PG_GETARG_FLOAT4(1);
! float4 result;
result = arg1 * arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2),
! arg1 == 0 || arg2 == 0);
! PG_RETURN_FLOAT4(result);
}
Datum
***************
*** 819,825 ****
{
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 arg2 = PG_GETARG_FLOAT4(1);
! double result;
if (arg2 == 0.0)
ereport(ERROR,
--- 750,756 ----
{
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 arg2 = PG_GETARG_FLOAT4(1);
! float4 result;
if (arg2 == 0.0)
ereport(ERROR,
***************
*** 827,836 ****
errmsg("division by zero")));
/* Do division in float8, then check for overflow */
! result = (float8) arg1 / (float8) arg2;
! CheckFloat4Val(result);
! PG_RETURN_FLOAT4((float4) result);
}
/*
--- 758,767 ----
errmsg("division by zero")));
/* Do division in float8, then check for overflow */
! result = arg1 / arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
! PG_RETURN_FLOAT4(result);
}
/*
***************
*** 848,854 ****
result = arg1 + arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 779,785 ----
result = arg1 + arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 861,867 ****
result = arg1 - arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 792,798 ----
result = arg1 - arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 874,880 ****
result = arg1 * arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 805,812 ----
result = arg1 * arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2),
! arg1 == 0 || arg2 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 892,898 ****
result = arg1 / arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 824,830 ----
result = arg1 / arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 1142,1148 ****
{
float8 num = PG_GETARG_FLOAT8(0);
! CheckFloat4Val(num);
PG_RETURN_FLOAT4((float4) num);
}
--- 1074,1080 ----
{
float8 num = PG_GETARG_FLOAT8(0);
! CHECKFLOATVAL((float4) num, isinf(num), true);
PG_RETURN_FLOAT4((float4) num);
}
***************
*** 1157,1163 ****
float8 num = PG_GETARG_FLOAT8(0);
int32 result;
! if (num < INT_MIN || num > INT_MAX)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("integer out of range")));
--- 1089,1096 ----
float8 num = PG_GETARG_FLOAT8(0);
int32 result;
! /* 'Inf' is handled by INT_MAX */
! if (num < INT_MIN || num > INT_MAX || isnan(num))
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("integer out of range")));
***************
*** 1174,1188 ****
dtoi2(PG_FUNCTION_ARGS)
{
float8 num = PG_GETARG_FLOAT8(0);
- int16 result;
! if (num < SHRT_MIN || num > SHRT_MAX)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("smallint out of range")));
! result = (int16) rint(num);
! PG_RETURN_INT16(result);
}
--- 1107,1119 ----
dtoi2(PG_FUNCTION_ARGS)
{
float8 num = PG_GETARG_FLOAT8(0);
! if (num < SHRT_MIN || num > SHRT_MAX || isnan(num))
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("smallint out of range")));
! PG_RETURN_INT16((int16) rint(num));
}
***************
*** 1193,1202 ****
i4tod(PG_FUNCTION_ARGS)
{
int32 num = PG_GETARG_INT32(0);
- float8 result;
! result = num;
! PG_RETURN_FLOAT8(result);
}
--- 1124,1131 ----
i4tod(PG_FUNCTION_ARGS)
{
int32 num = PG_GETARG_INT32(0);
! PG_RETURN_FLOAT8((float8) num);
}
***************
*** 1207,1216 ****
i2tod(PG_FUNCTION_ARGS)
{
int16 num = PG_GETARG_INT16(0);
- float8 result;
! result = num;
! PG_RETURN_FLOAT8(result);
}
--- 1136,1143 ----
i2tod(PG_FUNCTION_ARGS)
{
int16 num = PG_GETARG_INT16(0);
! PG_RETURN_FLOAT8((float8) num);
}
***************
*** 1221,1235 ****
ftoi4(PG_FUNCTION_ARGS)
{
float4 num = PG_GETARG_FLOAT4(0);
- int32 result;
! if (num < INT_MIN || num > INT_MAX)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("integer out of range")));
! result = (int32) rint(num);
! PG_RETURN_INT32(result);
}
--- 1148,1160 ----
ftoi4(PG_FUNCTION_ARGS)
{
float4 num = PG_GETARG_FLOAT4(0);
! if (num < INT_MIN || num > INT_MAX || isnan(num))
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("integer out of range")));
! PG_RETURN_INT32((int32) rint(num));
}
***************
*** 1240,1268 ****
ftoi2(PG_FUNCTION_ARGS)
{
float4 num = PG_GETARG_FLOAT4(0);
- int16 result;
! if (num < SHRT_MIN || num > SHRT_MAX)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("smallint out of range")));
! result = (int16) rint(num);
! PG_RETURN_INT16(result);
}
/*
! * i4tof - converts an int4 number to a float8 number
*/
Datum
i4tof(PG_FUNCTION_ARGS)
{
int32 num = PG_GETARG_INT32(0);
- float4 result;
! result = num;
! PG_RETURN_FLOAT4(result);
}
--- 1165,1189 ----
ftoi2(PG_FUNCTION_ARGS)
{
float4 num = PG_GETARG_FLOAT4(0);
! if (num < SHRT_MIN || num > SHRT_MAX || isnan(num))
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("smallint out of range")));
! PG_RETURN_INT16((int16) rint(num));
}
/*
! * i4tof - converts an int4 number to a float4 number
*/
Datum
i4tof(PG_FUNCTION_ARGS)
{
int32 num = PG_GETARG_INT32(0);
! PG_RETURN_FLOAT4((float4) num);
}
***************
*** 1273,1282 ****
i2tof(PG_FUNCTION_ARGS)
{
int16 num = PG_GETARG_INT16(0);
- float4 result;
! result = num;
! PG_RETURN_FLOAT4(result);
}
--- 1194,1201 ----
i2tof(PG_FUNCTION_ARGS)
{
int16 num = PG_GETARG_INT16(0);
! PG_RETURN_FLOAT4((float4) num);
}
***************
*** 1395,1405 ****
dround(PG_FUNCTION_ARGS)
{
float8 arg1 = PG_GETARG_FLOAT8(0);
- float8 result;
-
- result = rint(arg1);
! PG_RETURN_FLOAT8(result);
}
/*
--- 1314,1321 ----
dround(PG_FUNCTION_ARGS)
{
float8 arg1 = PG_GETARG_FLOAT8(0);
! PG_RETURN_FLOAT8(rint(arg1));
}
/*
***************
*** 1485,1491 ****
result = sqrt(arg1);
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1401,1407 ----
result = sqrt(arg1);
! CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 1500,1505 ****
--- 1416,1422 ----
float8 result;
result = cbrt(arg1);
+ CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 1530,1545 ****
*/
errno = 0;
result = pow(arg1, arg2);
! if (errno != 0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("result is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1447,1458 ----
*/
errno = 0;
result = pow(arg1, arg2);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("result is out of range")));
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 1555,1575 ****
/*
* We must check both for errno getting set and for a NaN result, in order
! * to deal with the vagaries of different platforms. Also, a zero result
! * implies unreported underflow.
*/
errno = 0;
result = exp(arg1);
! if (errno != 0 || result == 0.0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("result is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1468,1483 ----
/*
* We must check both for errno getting set and for a NaN result, in order
! * to deal with the vagaries of different platforms.
*/
errno = 0;
result = exp(arg1);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("result is out of range")));
! CHECKFLOATVAL(result, isinf(arg1), false);
PG_RETURN_FLOAT8(result);
}
***************
*** 1598,1604 ****
result = log(arg1);
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1506,1512 ----
result = log(arg1);
! CHECKFLOATVAL(result, isinf(arg1), arg1 == 1);
PG_RETURN_FLOAT8(result);
}
***************
*** 1628,1634 ****
result = log10(arg1);
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1536,1542 ----
result = log10(arg1);
! CHECKFLOATVAL(result, isinf(arg1), arg1 == 1);
PG_RETURN_FLOAT8(result);
}
***************
*** 1644,1659 ****
errno = 0;
result = acos(arg1);
! if (errno != 0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1552,1563 ----
errno = 0;
result = acos(arg1);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CHECKFLOATVAL(result, isinf(arg1), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 1669,1684 ****
errno = 0;
result = asin(arg1);
! if (errno != 0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1573,1584 ----
errno = 0;
result = asin(arg1);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CHECKFLOATVAL(result, isinf(arg1), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 1694,1709 ****
errno = 0;
result = atan(arg1);
! if (errno != 0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1594,1605 ----
errno = 0;
result = atan(arg1);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CHECKFLOATVAL(result, isinf(arg1), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 1720,1735 ****
errno = 0;
result = atan2(arg1, arg2);
! if (errno != 0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1616,1627 ----
errno = 0;
result = atan2(arg1, arg2);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 1745,1760 ****
errno = 0;
result = cos(arg1);
! if (errno != 0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1637,1648 ----
errno = 0;
result = cos(arg1);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CHECKFLOATVAL(result, isinf(arg1), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 1770,1786 ****
errno = 0;
result = tan(arg1);
! if (errno != 0 || result == 0.0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
result = 1.0 / result;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1658,1670 ----
errno = 0;
result = tan(arg1);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
result = 1.0 / result;
! CHECKFLOATVAL(result, true /* cotan(pi/2) == inf */, true);
PG_RETURN_FLOAT8(result);
}
***************
*** 1796,1811 ****
errno = 0;
result = sin(arg1);
! if (errno != 0
! #ifdef HAVE_FINITE
! || !finite(result)
! #endif
! )
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1680,1691 ----
errno = 0;
result = sin(arg1);
! if (errno != 0)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CHECKFLOATVAL(result, isinf(arg1), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 1830,1836 ****
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1710,1716 ----
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("input is out of range")));
! CHECKFLOATVAL(result, true /* tan(pi/2) == Inf */, true);
PG_RETURN_FLOAT8(result);
}
***************
*** 1846,1852 ****
result = arg1 * (180.0 / M_PI);
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1726,1732 ----
result = arg1 * (180.0 / M_PI);
! CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 1872,1878 ****
result = arg1 * (M_PI / 180.0);
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 1752,1758 ----
result = arg1 * (M_PI / 180.0);
! CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 1963,1970 ****
N += 1.0;
sumX += newval;
sumX2 += newval * newval;
!
/*
* If we're invoked by nodeAgg, we can cheat and modify our first
* parameter in-place to reduce palloc overhead. Otherwise we construct a
--- 1843,1852 ----
N += 1.0;
sumX += newval;
+ CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newval), true);
sumX2 += newval * newval;
! CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newval), true);
!
/*
* If we're invoked by nodeAgg, we can cheat and modify our first
* parameter in-place to reduce palloc overhead. Otherwise we construct a
***************
*** 1999,2023 ****
float4_accum(PG_FUNCTION_ARGS)
{
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
! float4 newval4 = PG_GETARG_FLOAT4(1);
float8 *transvalues;
float8 N,
sumX,
! sumX2,
! newval;
transvalues = check_float8_array(transarray, "float4_accum", 3);
N = transvalues[0];
sumX = transvalues[1];
sumX2 = transvalues[2];
- /* Do arithmetic in float8 for best accuracy */
- newval = newval4;
-
N += 1.0;
sumX += newval;
sumX2 += newval * newval;
!
/*
* If we're invoked by nodeAgg, we can cheat and modify our first
* parameter in-place to reduce palloc overhead. Otherwise we construct a
--- 1881,1904 ----
float4_accum(PG_FUNCTION_ARGS)
{
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
! /* do computations as float8 */
! float8 newval = PG_GETARG_FLOAT4(1);
float8 *transvalues;
float8 N,
sumX,
! sumX2;
transvalues = check_float8_array(transarray, "float4_accum", 3);
N = transvalues[0];
sumX = transvalues[1];
sumX2 = transvalues[2];
N += 1.0;
sumX += newval;
+ CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newval), true);
sumX2 += newval * newval;
! CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newval), true);
!
/*
* If we're invoked by nodeAgg, we can cheat and modify our first
* parameter in-place to reduce palloc overhead. Otherwise we construct a
***************
*** 2088,2093 ****
--- 1969,1975 ----
PG_RETURN_NULL();
numerator = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
/* Watch out for roundoff error producing a negative numerator */
if (numerator <= 0.0)
***************
*** 2116,2121 ****
--- 1998,2004 ----
PG_RETURN_NULL();
numerator = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
/* Watch out for roundoff error producing a negative numerator */
if (numerator <= 0.0)
***************
*** 2144,2149 ****
--- 2027,2033 ----
PG_RETURN_NULL();
numerator = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
/* Watch out for roundoff error producing a negative numerator */
if (numerator <= 0.0)
***************
*** 2172,2177 ****
--- 2056,2062 ----
PG_RETURN_NULL();
numerator = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
/* Watch out for roundoff error producing a negative numerator */
if (numerator <= 0.0)
***************
*** 2220,2230 ****
N += 1.0;
sumX += newvalX;
sumX2 += newvalX * newvalX;
sumY += newvalY;
sumY2 += newvalY * newvalY;
sumXY += newvalX * newvalY;
!
/*
* If we're invoked by nodeAgg, we can cheat and modify our first
* parameter in-place to reduce palloc overhead. Otherwise we construct a
--- 2105,2121 ----
N += 1.0;
sumX += newvalX;
+ CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newvalX), true);
sumX2 += newvalX * newvalX;
+ CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newvalX), true);
sumY += newvalY;
+ CHECKFLOATVAL(sumY, isinf(transvalues[3]) || isinf(newvalY), true);
sumY2 += newvalY * newvalY;
+ CHECKFLOATVAL(sumY2, isinf(transvalues[4]) || isinf(newvalY), true);
sumXY += newvalX * newvalY;
! CHECKFLOATVAL(sumXY, isinf(transvalues[5]) || isinf(newvalX) ||
! isinf(newvalY), true);
!
/*
* If we're invoked by nodeAgg, we can cheat and modify our first
* parameter in-place to reduce palloc overhead. Otherwise we construct a
***************
*** 2282,2287 ****
--- 2173,2179 ----
PG_RETURN_NULL();
numerator = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
/* Watch out for roundoff error producing a negative numerator */
if (numerator <= 0.0)
***************
*** 2310,2315 ****
--- 2202,2208 ----
PG_RETURN_NULL();
numerator = N * sumY2 - sumY * sumY;
+ CHECKFLOATVAL(numerator, isinf(sumY2) || isinf(sumY), true);
/* Watch out for roundoff error producing a negative numerator */
if (numerator <= 0.0)
***************
*** 2340,2345 ****
--- 2233,2240 ----
PG_RETURN_NULL();
numerator = N * sumXY - sumX * sumY;
+ CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) ||
+ isinf(sumY), true);
/* A negative result is valid here */
***************
*** 2406,2411 ****
--- 2301,2308 ----
PG_RETURN_NULL();
numerator = N * sumXY - sumX * sumY;
+ CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) ||
+ isinf(sumY), true);
PG_RETURN_FLOAT8(numerator / (N * N));
}
***************
*** 2432,2437 ****
--- 2329,2336 ----
PG_RETURN_NULL();
numerator = N * sumXY - sumX * sumY;
+ CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) ||
+ isinf(sumY), true);
PG_RETURN_FLOAT8(numerator / (N * (N - 1.0)));
}
***************
*** 2464,2471 ****
--- 2363,2374 ----
PG_RETURN_NULL();
numeratorX = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true);
numeratorY = N * sumY2 - sumY * sumY;
+ CHECKFLOATVAL(numeratorY, isinf(sumY2) || isinf(sumY), true);
numeratorXY = N * sumXY - sumX * sumY;
+ CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) ||
+ isinf(sumY), true);
if (numeratorX <= 0 || numeratorY <= 0)
PG_RETURN_NULL();
***************
*** 2501,2508 ****
--- 2404,2415 ----
PG_RETURN_NULL();
numeratorX = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true);
numeratorY = N * sumY2 - sumY * sumY;
+ CHECKFLOATVAL(numeratorY, isinf(sumY2) || isinf(sumY), true);
numeratorXY = N * sumXY - sumX * sumY;
+ CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) ||
+ isinf(sumY), true);
if (numeratorX <= 0)
PG_RETURN_NULL();
/* per spec, horizontal line produces 1.0 */
***************
*** 2538,2544 ****
--- 2445,2454 ----
PG_RETURN_NULL();
numeratorX = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true);
numeratorXY = N * sumXY - sumX * sumY;
+ CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) ||
+ isinf(sumY), true);
if (numeratorX <= 0)
PG_RETURN_NULL();
***************
*** 2570,2576 ****
--- 2480,2489 ----
PG_RETURN_NULL();
numeratorX = N * sumX2 - sumX * sumX;
+ CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true);
numeratorXXY = sumY * sumX2 - sumX * sumXY;
+ CHECKFLOATVAL(numeratorXXY, isinf(sumY) || isinf(sumX2) ||
+ isinf(sumX) || isinf(sumXY), true);
if (numeratorX <= 0)
PG_RETURN_NULL();
***************
*** 2598,2604 ****
float8 result;
result = arg1 + arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 2511,2517 ----
float8 result;
result = arg1 + arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 2610,2616 ****
float8 result;
result = arg1 - arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 2523,2529 ----
float8 result;
result = arg1 - arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 2622,2628 ****
float8 result;
result = arg1 * arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 2535,2542 ----
float8 result;
result = arg1 * arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2),
! arg1 == 0 || arg2 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 2639,2645 ****
errmsg("division by zero")));
result = arg1 / arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 2553,2559 ----
errmsg("division by zero")));
result = arg1 / arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 2658,2664 ****
result = arg1 + arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 2572,2578 ----
result = arg1 + arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 2671,2677 ****
result = arg1 - arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 2585,2591 ----
result = arg1 - arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
PG_RETURN_FLOAT8(result);
}
***************
*** 2684,2690 ****
result = arg1 * arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 2598,2605 ----
result = arg1 * arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2),
! arg1 == 0 || arg2 == 0);
PG_RETURN_FLOAT8(result);
}
***************
*** 2702,2708 ****
result = arg1 / arg2;
! CheckFloat8Val(result);
PG_RETURN_FLOAT8(result);
}
--- 2617,2623 ----
result = arg1 / arg2;
! CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
Index: src/backend/utils/adt/int.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/int.c,v
retrieving revision 1.75
diff -c -c -r1.75 int.c
*** src/backend/utils/adt/int.c 4 Oct 2006 00:29:59 -0000 1.75
--- src/backend/utils/adt/int.c 30 Dec 2006 18:19:57 -0000
***************
*** 1124,1129 ****
--- 1124,1134 ----
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
+
+ /* SELECT ((-2147483648)::int4) % (-1); causes a floating point exception */
+ if (arg1 == INT_MIN && arg2 == -1)
+ PG_RETURN_INT32(0);
+
/* No overflow is possible */
PG_RETURN_INT32(arg1 % arg2);
Index: src/test/regress/expected/float4-exp-three-digits.out
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/expected/float4-exp-three-digits.out,v
retrieving revision 1.7
diff -c -c -r1.7 float4-exp-three-digits.out
*** src/test/regress/expected/float4-exp-three-digits.out 7 Apr 2005 01:51:40 -0000 1.7
--- src/test/regress/expected/float4-exp-three-digits.out 30 Dec 2006 18:19:59 -0000
***************
*** 8,20 ****
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
ERROR: type "real" value out of range: overflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
ERROR: type "real" value out of range: overflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
ERROR: type "real" value out of range: underflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
ERROR: type "real" value out of range: underflow
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
--- 8,20 ----
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e50');
ERROR: type "real" value out of range: overflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e50');
ERROR: type "real" value out of range: overflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-50');
ERROR: type "real" value out of range: underflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-50');
ERROR: type "real" value out of range: underflow
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
Index: src/test/regress/expected/float4.out
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/expected/float4.out,v
retrieving revision 1.13
diff -c -c -r1.13 float4.out
*** src/test/regress/expected/float4.out 7 Apr 2005 01:51:40 -0000 1.13
--- src/test/regress/expected/float4.out 30 Dec 2006 18:19:59 -0000
***************
*** 8,21 ****
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
! ERROR: type "real" value out of range: overflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
! ERROR: type "real" value out of range: overflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
! ERROR: type "real" value out of range: underflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
! ERROR: type "real" value out of range: underflow
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type real: ""
--- 8,21 ----
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e50');
! ERROR: value out of range: overflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e50');
! ERROR: value out of range: overflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-50');
! ERROR: value out of range: underflow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-50');
! ERROR: value out of range: underflow
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type real: ""
***************
*** 72,78 ****
SELECT ' INFINITY x'::float4;
ERROR: invalid input syntax for type real: " INFINITY x"
SELECT 'Infinity'::float4 + 100.0;
! ERROR: type "double precision" value out of range: overflow
SELECT 'Infinity'::float4 / 'Infinity'::float4;
?column?
----------
--- 72,82 ----
SELECT ' INFINITY x'::float4;
ERROR: invalid input syntax for type real: " INFINITY x"
SELECT 'Infinity'::float4 + 100.0;
! ?column?
! ----------
! Infinity
! (1 row)
!
SELECT 'Infinity'::float4 / 'Infinity'::float4;
?column?
----------
Index: src/test/regress/expected/float8.out
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/expected/float8.out,v
retrieving revision 1.24
diff -c -c -r1.24 float8.out
*** src/test/regress/expected/float8.out 8 Jun 2005 21:15:29 -0000 1.24
--- src/test/regress/expected/float8.out 30 Dec 2006 18:19:59 -0000
***************
*** 72,78 ****
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
SELECT 'Infinity'::float8 + 100.0;
! ERROR: type "double precision" value out of range: overflow
SELECT 'Infinity'::float8 / 'Infinity'::float8;
?column?
----------
--- 72,82 ----
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
SELECT 'Infinity'::float8 + 100.0;
! ?column?
! ----------
! Infinity
! (1 row)
!
SELECT 'Infinity'::float8 / 'Infinity'::float8;
?column?
----------
***************
*** 342,356 ****
SET f1 = FLOAT8_TBL.f1 * '-1'
WHERE FLOAT8_TBL.f1 > '0.0';
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
! ERROR: type "double precision" value out of range: overflow
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
! ERROR: result is out of range
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
ERROR: cannot take logarithm of zero
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
ERROR: cannot take logarithm of a negative number
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
! ERROR: result is out of range
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
ERROR: division by zero
SELECT '' AS five, * FROM FLOAT8_TBL;
--- 346,360 ----
SET f1 = FLOAT8_TBL.f1 * '-1'
WHERE FLOAT8_TBL.f1 > '0.0';
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
! ERROR: value out of range: overflow
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
! ERROR: value out of range: overflow
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
ERROR: cannot take logarithm of zero
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
ERROR: cannot take logarithm of a negative number
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
! ERROR: value out of range: underflow
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
ERROR: division by zero
SELECT '' AS five, * FROM FLOAT8_TBL;
Index: src/test/regress/sql/float4.sql
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/sql/float4.sql,v
retrieving revision 1.8
diff -c -c -r1.8 float4.sql
*** src/test/regress/sql/float4.sql 7 Apr 2005 01:51:41 -0000 1.8
--- src/test/regress/sql/float4.sql 30 Dec 2006 18:19:59 -0000
***************
*** 11,20 ****
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
--- 11,20 ----
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e50');
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e50');
! INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-50');
! INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-50');
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster