mirror of
https://github.com/postgres/postgres.git
synced 2025-06-29 10:41:53 +03:00
Fix float4/8 to handle Infinity and Nan consistently, e.g. Infinity is a
valid result from a computation if one of the input values was infinity. The previous code assumed an operation that returned infinity was an overflow. Handle underflow/overflow consistently, and add checks for aggregate overflow. Consistently prevent Inf/Nan from being cast to integer data types. Fix INT_MIN % -1 to prevent overflow. Update regression results for new error text. Per report from Roman Kononov.
This commit is contained in:
@ -8,52 +8,13 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.131 2006/12/23 02:13:24 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.132 2007/01/02 20:00:49 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
/*----------
|
|
||||||
* 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 "postgres.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <float.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
/* for finite() on Solaris */
|
/* for finite() on Solaris */
|
||||||
@ -91,21 +52,30 @@ static const uint32 nan[2] = {0xffffffff, 0x7fffffff};
|
|||||||
#define MAXFLOATWIDTH 64
|
#define MAXFLOATWIDTH 64
|
||||||
#define MAXDOUBLEWIDTH 128
|
#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 ========== */
|
/* ========== 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 */
|
/* Configurable GUC parameter */
|
||||||
int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
|
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 float4_cmp_internal(float4 a, float4 b);
|
||||||
static int float8_cmp_internal(float8 a, float8 b);
|
static int float8_cmp_internal(float8 a, float8 b);
|
||||||
|
|
||||||
@ -204,44 +174,6 @@ is_infinite(double val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
* float4in - converts "num" to float
|
||||||
* restricted syntax:
|
* restricted syntax:
|
||||||
@ -369,8 +301,7 @@ float4in(PG_FUNCTION_ARGS)
|
|||||||
* if we get here, we have a legal double, still need to check to see if
|
* if we get here, we have a legal double, still need to check to see if
|
||||||
* it's a legal float4
|
* it's a legal float4
|
||||||
*/
|
*/
|
||||||
if (!isinf(val))
|
CHECKFLOATVAL((float4) val, isinf(val), val == 0);
|
||||||
CheckFloat4Val(val);
|
|
||||||
|
|
||||||
PG_RETURN_FLOAT4((float4) val);
|
PG_RETURN_FLOAT4((float4) val);
|
||||||
}
|
}
|
||||||
@ -558,8 +489,7 @@ float8in(PG_FUNCTION_ARGS)
|
|||||||
errmsg("invalid input syntax for type double precision: \"%s\"",
|
errmsg("invalid input syntax for type double precision: \"%s\"",
|
||||||
orig_num)));
|
orig_num)));
|
||||||
|
|
||||||
if (!isinf(val))
|
CHECKFLOATVAL(val, true, true);
|
||||||
CheckFloat8Val(val);
|
|
||||||
|
|
||||||
PG_RETURN_FLOAT8(val);
|
PG_RETURN_FLOAT8(val);
|
||||||
}
|
}
|
||||||
@ -652,8 +582,12 @@ Datum
|
|||||||
float4um(PG_FUNCTION_ARGS)
|
float4um(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
float4 arg1 = PG_GETARG_FLOAT4(0);
|
float4 arg1 = PG_GETARG_FLOAT4(0);
|
||||||
|
float4 result;
|
||||||
|
|
||||||
PG_RETURN_FLOAT4((float4) -arg1);
|
result = ((arg1 != 0) ? -(arg1) : arg1);
|
||||||
|
|
||||||
|
CHECKFLOATVAL(result, isinf(arg1), true);
|
||||||
|
PG_RETURN_FLOAT4(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
@ -705,12 +639,8 @@ Datum
|
|||||||
float8abs(PG_FUNCTION_ARGS)
|
float8abs(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
float8 arg1 = PG_GETARG_FLOAT8(0);
|
float8 arg1 = PG_GETARG_FLOAT8(0);
|
||||||
float8 result;
|
|
||||||
|
|
||||||
result = fabs(arg1);
|
PG_RETURN_FLOAT8(fabs(arg1));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
|
||||||
PG_RETURN_FLOAT8(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -725,7 +655,7 @@ float8um(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = ((arg1 != 0) ? -(arg1) : arg1);
|
result = ((arg1 != 0) ? -(arg1) : arg1);
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,13 +711,20 @@ float8smaller(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
float4pl(PG_FUNCTION_ARGS)
|
float4pl(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
float4 arg1 = PG_GETARG_FLOAT4(0);
|
float8 arg1 = PG_GETARG_FLOAT4(0);
|
||||||
float4 arg2 = PG_GETARG_FLOAT4(1);
|
float8 arg2 = PG_GETARG_FLOAT4(1);
|
||||||
double result;
|
float4 result;
|
||||||
|
|
||||||
result = arg1 + arg2;
|
result = arg1 + arg2;
|
||||||
CheckFloat4Val(result);
|
/*
|
||||||
PG_RETURN_FLOAT4((float4) result);
|
* There isn't any way to check for underflow of addition/subtraction
|
||||||
|
* because numbers near the underflow value have been already been
|
||||||
|
* to the point where we can't detect the that the two values
|
||||||
|
* were originally different, e.g. on x86, '1e-45'::float4 ==
|
||||||
|
* '2e-45'::float4 == 1.4013e-45.
|
||||||
|
*/
|
||||||
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
|
PG_RETURN_FLOAT4(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
@ -795,11 +732,11 @@ float4mi(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
float4 arg1 = PG_GETARG_FLOAT4(0);
|
float4 arg1 = PG_GETARG_FLOAT4(0);
|
||||||
float4 arg2 = PG_GETARG_FLOAT4(1);
|
float4 arg2 = PG_GETARG_FLOAT4(1);
|
||||||
double result;
|
float4 result;
|
||||||
|
|
||||||
result = arg1 - arg2;
|
result = arg1 - arg2;
|
||||||
CheckFloat4Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
PG_RETURN_FLOAT4((float4) result);
|
PG_RETURN_FLOAT4(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
@ -807,11 +744,12 @@ float4mul(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
float4 arg1 = PG_GETARG_FLOAT4(0);
|
float4 arg1 = PG_GETARG_FLOAT4(0);
|
||||||
float4 arg2 = PG_GETARG_FLOAT4(1);
|
float4 arg2 = PG_GETARG_FLOAT4(1);
|
||||||
double result;
|
float4 result;
|
||||||
|
|
||||||
result = arg1 * arg2;
|
result = arg1 * arg2;
|
||||||
CheckFloat4Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2),
|
||||||
PG_RETURN_FLOAT4((float4) result);
|
arg1 == 0 || arg2 == 0);
|
||||||
|
PG_RETURN_FLOAT4(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
@ -819,7 +757,7 @@ float4div(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
float4 arg1 = PG_GETARG_FLOAT4(0);
|
float4 arg1 = PG_GETARG_FLOAT4(0);
|
||||||
float4 arg2 = PG_GETARG_FLOAT4(1);
|
float4 arg2 = PG_GETARG_FLOAT4(1);
|
||||||
double result;
|
float4 result;
|
||||||
|
|
||||||
if (arg2 == 0.0)
|
if (arg2 == 0.0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -827,10 +765,10 @@ float4div(PG_FUNCTION_ARGS)
|
|||||||
errmsg("division by zero")));
|
errmsg("division by zero")));
|
||||||
|
|
||||||
/* Do division in float8, then check for overflow */
|
/* Do division in float8, then check for overflow */
|
||||||
result = (float8) arg1 / (float8) arg2;
|
result = arg1 / arg2;
|
||||||
|
|
||||||
CheckFloat4Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
|
||||||
PG_RETURN_FLOAT4((float4) result);
|
PG_RETURN_FLOAT4(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -848,7 +786,7 @@ float8pl(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 + arg2;
|
result = arg1 + arg2;
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,7 +799,7 @@ float8mi(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 - arg2;
|
result = arg1 - arg2;
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,7 +812,8 @@ float8mul(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 * arg2;
|
result = arg1 * arg2;
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2),
|
||||||
|
arg1 == 0 || arg2 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,7 +831,7 @@ float8div(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 / arg2;
|
result = arg1 / arg2;
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1142,7 +1081,7 @@ dtof(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
float8 num = PG_GETARG_FLOAT8(0);
|
float8 num = PG_GETARG_FLOAT8(0);
|
||||||
|
|
||||||
CheckFloat4Val(num);
|
CHECKFLOATVAL((float4) num, isinf(num), num == 0);
|
||||||
|
|
||||||
PG_RETURN_FLOAT4((float4) num);
|
PG_RETURN_FLOAT4((float4) num);
|
||||||
}
|
}
|
||||||
@ -1157,7 +1096,8 @@ dtoi4(PG_FUNCTION_ARGS)
|
|||||||
float8 num = PG_GETARG_FLOAT8(0);
|
float8 num = PG_GETARG_FLOAT8(0);
|
||||||
int32 result;
|
int32 result;
|
||||||
|
|
||||||
if (num < INT_MIN || num > INT_MAX)
|
/* 'Inf' is handled by INT_MAX */
|
||||||
|
if (num < INT_MIN || num > INT_MAX || isnan(num))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("integer out of range")));
|
errmsg("integer out of range")));
|
||||||
@ -1174,15 +1114,13 @@ Datum
|
|||||||
dtoi2(PG_FUNCTION_ARGS)
|
dtoi2(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
float8 num = PG_GETARG_FLOAT8(0);
|
float8 num = PG_GETARG_FLOAT8(0);
|
||||||
int16 result;
|
|
||||||
|
|
||||||
if (num < SHRT_MIN || num > SHRT_MAX)
|
if (num < SHRT_MIN || num > SHRT_MAX || isnan(num))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("smallint out of range")));
|
errmsg("smallint out of range")));
|
||||||
|
|
||||||
result = (int16) rint(num);
|
PG_RETURN_INT16((int16) rint(num));
|
||||||
PG_RETURN_INT16(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1193,10 +1131,8 @@ Datum
|
|||||||
i4tod(PG_FUNCTION_ARGS)
|
i4tod(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int32 num = PG_GETARG_INT32(0);
|
int32 num = PG_GETARG_INT32(0);
|
||||||
float8 result;
|
|
||||||
|
|
||||||
result = num;
|
PG_RETURN_FLOAT8((float8) num);
|
||||||
PG_RETURN_FLOAT8(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1207,10 +1143,8 @@ Datum
|
|||||||
i2tod(PG_FUNCTION_ARGS)
|
i2tod(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int16 num = PG_GETARG_INT16(0);
|
int16 num = PG_GETARG_INT16(0);
|
||||||
float8 result;
|
|
||||||
|
|
||||||
result = num;
|
PG_RETURN_FLOAT8((float8) num);
|
||||||
PG_RETURN_FLOAT8(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1221,15 +1155,13 @@ Datum
|
|||||||
ftoi4(PG_FUNCTION_ARGS)
|
ftoi4(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
float4 num = PG_GETARG_FLOAT4(0);
|
float4 num = PG_GETARG_FLOAT4(0);
|
||||||
int32 result;
|
|
||||||
|
|
||||||
if (num < INT_MIN || num > INT_MAX)
|
if (num < INT_MIN || num > INT_MAX || isnan(num))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("integer out of range")));
|
errmsg("integer out of range")));
|
||||||
|
|
||||||
result = (int32) rint(num);
|
PG_RETURN_INT32((int32) rint(num));
|
||||||
PG_RETURN_INT32(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1240,29 +1172,25 @@ Datum
|
|||||||
ftoi2(PG_FUNCTION_ARGS)
|
ftoi2(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
float4 num = PG_GETARG_FLOAT4(0);
|
float4 num = PG_GETARG_FLOAT4(0);
|
||||||
int16 result;
|
|
||||||
|
|
||||||
if (num < SHRT_MIN || num > SHRT_MAX)
|
if (num < SHRT_MIN || num > SHRT_MAX || isnan(num))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("smallint out of range")));
|
errmsg("smallint out of range")));
|
||||||
|
|
||||||
result = (int16) rint(num);
|
PG_RETURN_INT16((int16) rint(num));
|
||||||
PG_RETURN_INT16(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* i4tof - converts an int4 number to a float8 number
|
* i4tof - converts an int4 number to a float4 number
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
i4tof(PG_FUNCTION_ARGS)
|
i4tof(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int32 num = PG_GETARG_INT32(0);
|
int32 num = PG_GETARG_INT32(0);
|
||||||
float4 result;
|
|
||||||
|
|
||||||
result = num;
|
PG_RETURN_FLOAT4((float4) num);
|
||||||
PG_RETURN_FLOAT4(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1273,10 +1201,8 @@ Datum
|
|||||||
i2tof(PG_FUNCTION_ARGS)
|
i2tof(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int16 num = PG_GETARG_INT16(0);
|
int16 num = PG_GETARG_INT16(0);
|
||||||
float4 result;
|
|
||||||
|
|
||||||
result = num;
|
PG_RETURN_FLOAT4((float4) num);
|
||||||
PG_RETURN_FLOAT4(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1395,11 +1321,8 @@ Datum
|
|||||||
dround(PG_FUNCTION_ARGS)
|
dround(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
float8 arg1 = PG_GETARG_FLOAT8(0);
|
float8 arg1 = PG_GETARG_FLOAT8(0);
|
||||||
float8 result;
|
|
||||||
|
|
||||||
result = rint(arg1);
|
PG_RETURN_FLOAT8(rint(arg1));
|
||||||
|
|
||||||
PG_RETURN_FLOAT8(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1485,7 +1408,7 @@ dsqrt(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = sqrt(arg1);
|
result = sqrt(arg1);
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1500,6 +1423,7 @@ dcbrt(PG_FUNCTION_ARGS)
|
|||||||
float8 result;
|
float8 result;
|
||||||
|
|
||||||
result = cbrt(arg1);
|
result = cbrt(arg1);
|
||||||
|
CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1530,16 +1454,12 @@ dpow(PG_FUNCTION_ARGS)
|
|||||||
*/
|
*/
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = pow(arg1, arg2);
|
result = pow(arg1, arg2);
|
||||||
if (errno != 0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("result is out of range")));
|
errmsg("result is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1555,21 +1475,16 @@ dexp(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* We must check both for errno getting set and for a NaN result, in order
|
* 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
|
* to deal with the vagaries of different platforms.
|
||||||
* implies unreported underflow.
|
|
||||||
*/
|
*/
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = exp(arg1);
|
result = exp(arg1);
|
||||||
if (errno != 0 || result == 0.0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("result is out of range")));
|
errmsg("result is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), false);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1598,7 +1513,7 @@ dlog1(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = log(arg1);
|
result = log(arg1);
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), arg1 == 1);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1628,7 +1543,7 @@ dlog10(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = log10(arg1);
|
result = log10(arg1);
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), arg1 == 1);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1644,16 +1559,12 @@ dacos(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = acos(arg1);
|
result = acos(arg1);
|
||||||
if (errno != 0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("input is out of range")));
|
errmsg("input is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1669,16 +1580,12 @@ dasin(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = asin(arg1);
|
result = asin(arg1);
|
||||||
if (errno != 0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("input is out of range")));
|
errmsg("input is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1694,16 +1601,12 @@ datan(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = atan(arg1);
|
result = atan(arg1);
|
||||||
if (errno != 0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("input is out of range")));
|
errmsg("input is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1720,16 +1623,12 @@ datan2(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = atan2(arg1, arg2);
|
result = atan2(arg1, arg2);
|
||||||
if (errno != 0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("input is out of range")));
|
errmsg("input is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1745,16 +1644,12 @@ dcos(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = cos(arg1);
|
result = cos(arg1);
|
||||||
if (errno != 0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("input is out of range")));
|
errmsg("input is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1770,17 +1665,13 @@ dcot(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = tan(arg1);
|
result = tan(arg1);
|
||||||
if (errno != 0 || result == 0.0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("input is out of range")));
|
errmsg("input is out of range")));
|
||||||
|
|
||||||
result = 1.0 / result;
|
result = 1.0 / result;
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, true /* cotan(pi/2) == inf */, true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1796,16 +1687,12 @@ dsin(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = sin(arg1);
|
result = sin(arg1);
|
||||||
if (errno != 0
|
if (errno != 0)
|
||||||
#ifdef HAVE_FINITE
|
|
||||||
|| !finite(result)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("input is out of range")));
|
errmsg("input is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1830,7 +1717,7 @@ dtan(PG_FUNCTION_ARGS)
|
|||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("input is out of range")));
|
errmsg("input is out of range")));
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, true /* tan(pi/2) == Inf */, true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1846,7 +1733,7 @@ degrees(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 * (180.0 / M_PI);
|
result = arg1 * (180.0 / M_PI);
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1872,7 +1759,7 @@ radians(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 * (M_PI / 180.0);
|
result = arg1 * (M_PI / 180.0);
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1963,7 +1850,9 @@ float8_accum(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
N += 1.0;
|
N += 1.0;
|
||||||
sumX += newval;
|
sumX += newval;
|
||||||
|
CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newval), true);
|
||||||
sumX2 += newval * newval;
|
sumX2 += newval * newval;
|
||||||
|
CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newval), true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're invoked by nodeAgg, we can cheat and modify our first
|
* If we're invoked by nodeAgg, we can cheat and modify our first
|
||||||
@ -1999,24 +1888,23 @@ Datum
|
|||||||
float4_accum(PG_FUNCTION_ARGS)
|
float4_accum(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
|
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
float4 newval4 = PG_GETARG_FLOAT4(1);
|
/* do computations as float8 */
|
||||||
|
float8 newval = PG_GETARG_FLOAT4(1);
|
||||||
float8 *transvalues;
|
float8 *transvalues;
|
||||||
float8 N,
|
float8 N,
|
||||||
sumX,
|
sumX,
|
||||||
sumX2,
|
sumX2;
|
||||||
newval;
|
|
||||||
|
|
||||||
transvalues = check_float8_array(transarray, "float4_accum", 3);
|
transvalues = check_float8_array(transarray, "float4_accum", 3);
|
||||||
N = transvalues[0];
|
N = transvalues[0];
|
||||||
sumX = transvalues[1];
|
sumX = transvalues[1];
|
||||||
sumX2 = transvalues[2];
|
sumX2 = transvalues[2];
|
||||||
|
|
||||||
/* Do arithmetic in float8 for best accuracy */
|
|
||||||
newval = newval4;
|
|
||||||
|
|
||||||
N += 1.0;
|
N += 1.0;
|
||||||
sumX += newval;
|
sumX += newval;
|
||||||
|
CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newval), true);
|
||||||
sumX2 += newval * newval;
|
sumX2 += newval * newval;
|
||||||
|
CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newval), true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're invoked by nodeAgg, we can cheat and modify our first
|
* If we're invoked by nodeAgg, we can cheat and modify our first
|
||||||
@ -2088,6 +1976,7 @@ float8_var_pop(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumX2 - sumX * sumX;
|
numerator = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
|
||||||
|
|
||||||
/* Watch out for roundoff error producing a negative numerator */
|
/* Watch out for roundoff error producing a negative numerator */
|
||||||
if (numerator <= 0.0)
|
if (numerator <= 0.0)
|
||||||
@ -2116,6 +2005,7 @@ float8_var_samp(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumX2 - sumX * sumX;
|
numerator = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
|
||||||
|
|
||||||
/* Watch out for roundoff error producing a negative numerator */
|
/* Watch out for roundoff error producing a negative numerator */
|
||||||
if (numerator <= 0.0)
|
if (numerator <= 0.0)
|
||||||
@ -2144,6 +2034,7 @@ float8_stddev_pop(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumX2 - sumX * sumX;
|
numerator = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
|
||||||
|
|
||||||
/* Watch out for roundoff error producing a negative numerator */
|
/* Watch out for roundoff error producing a negative numerator */
|
||||||
if (numerator <= 0.0)
|
if (numerator <= 0.0)
|
||||||
@ -2172,6 +2063,7 @@ float8_stddev_samp(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumX2 - sumX * sumX;
|
numerator = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
|
||||||
|
|
||||||
/* Watch out for roundoff error producing a negative numerator */
|
/* Watch out for roundoff error producing a negative numerator */
|
||||||
if (numerator <= 0.0)
|
if (numerator <= 0.0)
|
||||||
@ -2220,10 +2112,16 @@ float8_regr_accum(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
N += 1.0;
|
N += 1.0;
|
||||||
sumX += newvalX;
|
sumX += newvalX;
|
||||||
|
CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newvalX), true);
|
||||||
sumX2 += newvalX * newvalX;
|
sumX2 += newvalX * newvalX;
|
||||||
|
CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newvalX), true);
|
||||||
sumY += newvalY;
|
sumY += newvalY;
|
||||||
|
CHECKFLOATVAL(sumY, isinf(transvalues[3]) || isinf(newvalY), true);
|
||||||
sumY2 += newvalY * newvalY;
|
sumY2 += newvalY * newvalY;
|
||||||
|
CHECKFLOATVAL(sumY2, isinf(transvalues[4]) || isinf(newvalY), true);
|
||||||
sumXY += newvalX * newvalY;
|
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
|
* If we're invoked by nodeAgg, we can cheat and modify our first
|
||||||
@ -2282,6 +2180,7 @@ float8_regr_sxx(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumX2 - sumX * sumX;
|
numerator = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);
|
||||||
|
|
||||||
/* Watch out for roundoff error producing a negative numerator */
|
/* Watch out for roundoff error producing a negative numerator */
|
||||||
if (numerator <= 0.0)
|
if (numerator <= 0.0)
|
||||||
@ -2310,6 +2209,7 @@ float8_regr_syy(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumY2 - sumY * sumY;
|
numerator = N * sumY2 - sumY * sumY;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumY2) || isinf(sumY), true);
|
||||||
|
|
||||||
/* Watch out for roundoff error producing a negative numerator */
|
/* Watch out for roundoff error producing a negative numerator */
|
||||||
if (numerator <= 0.0)
|
if (numerator <= 0.0)
|
||||||
@ -2340,6 +2240,8 @@ float8_regr_sxy(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumXY - sumX * sumY;
|
numerator = N * sumXY - sumX * sumY;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) ||
|
||||||
|
isinf(sumY), true);
|
||||||
|
|
||||||
/* A negative result is valid here */
|
/* A negative result is valid here */
|
||||||
|
|
||||||
@ -2406,6 +2308,8 @@ float8_covar_pop(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumXY - sumX * sumY;
|
numerator = N * sumXY - sumX * sumY;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) ||
|
||||||
|
isinf(sumY), true);
|
||||||
|
|
||||||
PG_RETURN_FLOAT8(numerator / (N * N));
|
PG_RETURN_FLOAT8(numerator / (N * N));
|
||||||
}
|
}
|
||||||
@ -2432,6 +2336,8 @@ float8_covar_samp(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numerator = N * sumXY - sumX * sumY;
|
numerator = N * sumXY - sumX * sumY;
|
||||||
|
CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) ||
|
||||||
|
isinf(sumY), true);
|
||||||
|
|
||||||
PG_RETURN_FLOAT8(numerator / (N * (N - 1.0)));
|
PG_RETURN_FLOAT8(numerator / (N * (N - 1.0)));
|
||||||
}
|
}
|
||||||
@ -2464,8 +2370,12 @@ float8_corr(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numeratorX = N * sumX2 - sumX * sumX;
|
numeratorX = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true);
|
||||||
numeratorY = N * sumY2 - sumY * sumY;
|
numeratorY = N * sumY2 - sumY * sumY;
|
||||||
|
CHECKFLOATVAL(numeratorY, isinf(sumY2) || isinf(sumY), true);
|
||||||
numeratorXY = N * sumXY - sumX * sumY;
|
numeratorXY = N * sumXY - sumX * sumY;
|
||||||
|
CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) ||
|
||||||
|
isinf(sumY), true);
|
||||||
if (numeratorX <= 0 || numeratorY <= 0)
|
if (numeratorX <= 0 || numeratorY <= 0)
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
@ -2501,8 +2411,12 @@ float8_regr_r2(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numeratorX = N * sumX2 - sumX * sumX;
|
numeratorX = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true);
|
||||||
numeratorY = N * sumY2 - sumY * sumY;
|
numeratorY = N * sumY2 - sumY * sumY;
|
||||||
|
CHECKFLOATVAL(numeratorY, isinf(sumY2) || isinf(sumY), true);
|
||||||
numeratorXY = N * sumXY - sumX * sumY;
|
numeratorXY = N * sumXY - sumX * sumY;
|
||||||
|
CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) ||
|
||||||
|
isinf(sumY), true);
|
||||||
if (numeratorX <= 0)
|
if (numeratorX <= 0)
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
/* per spec, horizontal line produces 1.0 */
|
/* per spec, horizontal line produces 1.0 */
|
||||||
@ -2538,7 +2452,10 @@ float8_regr_slope(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numeratorX = N * sumX2 - sumX * sumX;
|
numeratorX = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true);
|
||||||
numeratorXY = N * sumXY - sumX * sumY;
|
numeratorXY = N * sumXY - sumX * sumY;
|
||||||
|
CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) ||
|
||||||
|
isinf(sumY), true);
|
||||||
if (numeratorX <= 0)
|
if (numeratorX <= 0)
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
@ -2570,7 +2487,10 @@ float8_regr_intercept(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
numeratorX = N * sumX2 - sumX * sumX;
|
numeratorX = N * sumX2 - sumX * sumX;
|
||||||
|
CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true);
|
||||||
numeratorXXY = sumY * sumX2 - sumX * sumXY;
|
numeratorXXY = sumY * sumX2 - sumX * sumXY;
|
||||||
|
CHECKFLOATVAL(numeratorXXY, isinf(sumY) || isinf(sumX2) ||
|
||||||
|
isinf(sumX) || isinf(sumXY), true);
|
||||||
if (numeratorX <= 0)
|
if (numeratorX <= 0)
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
@ -2598,7 +2518,7 @@ float48pl(PG_FUNCTION_ARGS)
|
|||||||
float8 result;
|
float8 result;
|
||||||
|
|
||||||
result = arg1 + arg2;
|
result = arg1 + arg2;
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2610,7 +2530,7 @@ float48mi(PG_FUNCTION_ARGS)
|
|||||||
float8 result;
|
float8 result;
|
||||||
|
|
||||||
result = arg1 - arg2;
|
result = arg1 - arg2;
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2622,7 +2542,8 @@ float48mul(PG_FUNCTION_ARGS)
|
|||||||
float8 result;
|
float8 result;
|
||||||
|
|
||||||
result = arg1 * arg2;
|
result = arg1 * arg2;
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2),
|
||||||
|
arg1 == 0 || arg2 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2639,7 +2560,7 @@ float48div(PG_FUNCTION_ARGS)
|
|||||||
errmsg("division by zero")));
|
errmsg("division by zero")));
|
||||||
|
|
||||||
result = arg1 / arg2;
|
result = arg1 / arg2;
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2658,7 +2579,7 @@ float84pl(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 + arg2;
|
result = arg1 + arg2;
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2671,7 +2592,7 @@ float84mi(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 - arg2;
|
result = arg1 - arg2;
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2684,7 +2605,8 @@ float84mul(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 * arg2;
|
result = arg1 * arg2;
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2),
|
||||||
|
arg1 == 0 || arg2 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2702,7 +2624,7 @@ float84div(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
result = arg1 / arg2;
|
result = arg1 / arg2;
|
||||||
|
|
||||||
CheckFloat8Val(result);
|
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.75 2006/10/04 00:29:59 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.76 2007/01/02 20:00:49 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1124,6 +1124,11 @@ int4mod(PG_FUNCTION_ARGS)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
||||||
errmsg("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 */
|
/* No overflow is possible */
|
||||||
|
|
||||||
PG_RETURN_INT32(arg1 % arg2);
|
PG_RETURN_INT32(arg1 % arg2);
|
||||||
|
@ -8,14 +8,14 @@ INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 ');
|
|||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+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
|
-- test for over and under flow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
|
||||||
ERROR: type "real" value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
|
||||||
ERROR: type "real" value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
|
||||||
ERROR: type "real" value out of range: underflow
|
ERROR: value out of range: underflow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
|
||||||
ERROR: type "real" value out of range: underflow
|
ERROR: value out of range: underflow
|
||||||
-- bad input
|
-- bad input
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
|
||||||
ERROR: invalid input syntax for type real: ""
|
ERROR: invalid input syntax for type real: ""
|
||||||
@ -72,7 +72,11 @@ ERROR: invalid input syntax for type real: "NaN x"
|
|||||||
SELECT ' INFINITY x'::float4;
|
SELECT ' INFINITY x'::float4;
|
||||||
ERROR: invalid input syntax for type real: " INFINITY x"
|
ERROR: invalid input syntax for type real: " INFINITY x"
|
||||||
SELECT 'Infinity'::float4 + 100.0;
|
SELECT 'Infinity'::float4 + 100.0;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
?column?
|
||||||
|
----------
|
||||||
|
Infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT 'Infinity'::float4 / 'Infinity'::float4;
|
SELECT 'Infinity'::float4 / 'Infinity'::float4;
|
||||||
?column?
|
?column?
|
||||||
----------
|
----------
|
||||||
|
@ -8,14 +8,14 @@ INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 ');
|
|||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+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
|
-- test for over and under flow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
|
||||||
ERROR: type "real" value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
|
||||||
ERROR: type "real" value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
|
||||||
ERROR: type "real" value out of range: underflow
|
ERROR: value out of range: underflow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
|
||||||
ERROR: type "real" value out of range: underflow
|
ERROR: value out of range: underflow
|
||||||
-- bad input
|
-- bad input
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
|
||||||
ERROR: invalid input syntax for type real: ""
|
ERROR: invalid input syntax for type real: ""
|
||||||
@ -72,7 +72,11 @@ ERROR: invalid input syntax for type real: "NaN x"
|
|||||||
SELECT ' INFINITY x'::float4;
|
SELECT ' INFINITY x'::float4;
|
||||||
ERROR: invalid input syntax for type real: " INFINITY x"
|
ERROR: invalid input syntax for type real: " INFINITY x"
|
||||||
SELECT 'Infinity'::float4 + 100.0;
|
SELECT 'Infinity'::float4 + 100.0;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
?column?
|
||||||
|
----------
|
||||||
|
Infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT 'Infinity'::float4 / 'Infinity'::float4;
|
SELECT 'Infinity'::float4 / 'Infinity'::float4;
|
||||||
?column?
|
?column?
|
||||||
----------
|
----------
|
||||||
|
@ -72,7 +72,11 @@ ERROR: invalid input syntax for type double precision: "NaN x"
|
|||||||
SELECT ' INFINITY x'::float8;
|
SELECT ' INFINITY x'::float8;
|
||||||
ERROR: invalid input syntax for type double precision: " INFINITY x"
|
ERROR: invalid input syntax for type double precision: " INFINITY x"
|
||||||
SELECT 'Infinity'::float8 + 100.0;
|
SELECT 'Infinity'::float8 + 100.0;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
?column?
|
||||||
|
----------
|
||||||
|
Infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
||||||
?column?
|
?column?
|
||||||
----------
|
----------
|
||||||
@ -342,15 +346,15 @@ UPDATE FLOAT8_TBL
|
|||||||
SET f1 = FLOAT8_TBL.f1 * '-1'
|
SET f1 = FLOAT8_TBL.f1 * '-1'
|
||||||
WHERE FLOAT8_TBL.f1 > '0.0';
|
WHERE FLOAT8_TBL.f1 > '0.0';
|
||||||
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
||||||
ERROR: result is out of range
|
ERROR: value out of range: overflow
|
||||||
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
||||||
ERROR: cannot take logarithm of zero
|
ERROR: cannot take logarithm of zero
|
||||||
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
||||||
ERROR: cannot take logarithm of a negative number
|
ERROR: cannot take logarithm of a negative number
|
||||||
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
||||||
ERROR: result is out of range
|
ERROR: value out of range: underflow
|
||||||
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
||||||
ERROR: division by zero
|
ERROR: division by zero
|
||||||
SELECT '' AS five, * FROM FLOAT8_TBL;
|
SELECT '' AS five, * FROM FLOAT8_TBL;
|
||||||
|
@ -80,7 +80,11 @@ ERROR: invalid input syntax for type double precision: "NaN x"
|
|||||||
SELECT ' INFINITY x'::float8;
|
SELECT ' INFINITY x'::float8;
|
||||||
ERROR: invalid input syntax for type double precision: " INFINITY x"
|
ERROR: invalid input syntax for type double precision: " INFINITY x"
|
||||||
SELECT 'Infinity'::float8 + 100.0;
|
SELECT 'Infinity'::float8 + 100.0;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
?column?
|
||||||
|
----------
|
||||||
|
Infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
||||||
?column?
|
?column?
|
||||||
----------
|
----------
|
||||||
@ -350,15 +354,15 @@ UPDATE FLOAT8_TBL
|
|||||||
SET f1 = FLOAT8_TBL.f1 * '-1'
|
SET f1 = FLOAT8_TBL.f1 * '-1'
|
||||||
WHERE FLOAT8_TBL.f1 > '0.0';
|
WHERE FLOAT8_TBL.f1 > '0.0';
|
||||||
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
||||||
ERROR: result is out of range
|
ERROR: value out of range: overflow
|
||||||
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
||||||
ERROR: cannot take logarithm of zero
|
ERROR: cannot take logarithm of zero
|
||||||
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
||||||
ERROR: cannot take logarithm of a negative number
|
ERROR: cannot take logarithm of a negative number
|
||||||
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
||||||
ERROR: result is out of range
|
ERROR: value out of range: underflow
|
||||||
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
||||||
ERROR: division by zero
|
ERROR: division by zero
|
||||||
SELECT '' AS five, * FROM FLOAT8_TBL;
|
SELECT '' AS five, * FROM FLOAT8_TBL;
|
||||||
|
@ -80,7 +80,11 @@ ERROR: invalid input syntax for type double precision: "NaN x"
|
|||||||
SELECT ' INFINITY x'::float8;
|
SELECT ' INFINITY x'::float8;
|
||||||
ERROR: invalid input syntax for type double precision: " INFINITY x"
|
ERROR: invalid input syntax for type double precision: " INFINITY x"
|
||||||
SELECT 'Infinity'::float8 + 100.0;
|
SELECT 'Infinity'::float8 + 100.0;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
?column?
|
||||||
|
----------
|
||||||
|
Infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
||||||
?column?
|
?column?
|
||||||
----------
|
----------
|
||||||
@ -350,15 +354,15 @@ UPDATE FLOAT8_TBL
|
|||||||
SET f1 = FLOAT8_TBL.f1 * '-1'
|
SET f1 = FLOAT8_TBL.f1 * '-1'
|
||||||
WHERE FLOAT8_TBL.f1 > '0.0';
|
WHERE FLOAT8_TBL.f1 > '0.0';
|
||||||
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
||||||
ERROR: result is out of range
|
ERROR: value out of range: overflow
|
||||||
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
||||||
ERROR: cannot take logarithm of zero
|
ERROR: cannot take logarithm of zero
|
||||||
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
||||||
ERROR: cannot take logarithm of a negative number
|
ERROR: cannot take logarithm of a negative number
|
||||||
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
||||||
ERROR: result is out of range
|
ERROR: value out of range: underflow
|
||||||
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
||||||
ERROR: division by zero
|
ERROR: division by zero
|
||||||
SELECT '' AS five, * FROM FLOAT8_TBL;
|
SELECT '' AS five, * FROM FLOAT8_TBL;
|
||||||
|
@ -72,7 +72,11 @@ ERROR: invalid input syntax for type double precision: "NaN x"
|
|||||||
SELECT ' INFINITY x'::float8;
|
SELECT ' INFINITY x'::float8;
|
||||||
ERROR: invalid input syntax for type double precision: " INFINITY x"
|
ERROR: invalid input syntax for type double precision: " INFINITY x"
|
||||||
SELECT 'Infinity'::float8 + 100.0;
|
SELECT 'Infinity'::float8 + 100.0;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
?column?
|
||||||
|
----------
|
||||||
|
Infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
SELECT 'Infinity'::float8 / 'Infinity'::float8;
|
||||||
?column?
|
?column?
|
||||||
----------
|
----------
|
||||||
@ -342,15 +346,15 @@ UPDATE FLOAT8_TBL
|
|||||||
SET f1 = FLOAT8_TBL.f1 * '-1'
|
SET f1 = FLOAT8_TBL.f1 * '-1'
|
||||||
WHERE FLOAT8_TBL.f1 > '0.0';
|
WHERE FLOAT8_TBL.f1 > '0.0';
|
||||||
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
|
||||||
ERROR: type "double precision" value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
|
||||||
ERROR: result is out of range
|
ERROR: value out of range: overflow
|
||||||
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
|
||||||
ERROR: cannot take logarithm of zero
|
ERROR: cannot take logarithm of zero
|
||||||
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
|
||||||
ERROR: cannot take logarithm of a negative number
|
ERROR: cannot take logarithm of a negative number
|
||||||
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
|
||||||
ERROR: result is out of range
|
ERROR: value out of range: underflow
|
||||||
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
|
||||||
ERROR: division by zero
|
ERROR: division by zero
|
||||||
SELECT '' AS five, * FROM FLOAT8_TBL;
|
SELECT '' AS five, * FROM FLOAT8_TBL;
|
||||||
|
@ -11,10 +11,10 @@ INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+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
|
-- test for over and under flow
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
|
||||||
|
|
||||||
-- bad input
|
-- bad input
|
||||||
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
|
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
|
||||||
|
Reference in New Issue
Block a user