diff options
author | Neil Conway <neilc@samurai.com> | 2004-03-12 00:25:43 +0000 |
---|---|---|
committer | Neil Conway <neilc@samurai.com> | 2004-03-12 00:25:43 +0000 |
commit | bfd6f52b0e0f1c1d579bf385dedfebca229dfcf5 (patch) | |
tree | d93225b282bd93d404205aaa8138ce262ae4cbdc /src | |
parent | fe6e9221360116e440fc28e45b083eb0811682cd (diff) | |
download | postgresql-bfd6f52b0e0f1c1d579bf385dedfebca229dfcf5.tar.gz postgresql-bfd6f52b0e0f1c1d579bf385dedfebca229dfcf5.zip |
Allow 'Infinity' and '-Infinity' as input to the float4 and float8
types. Update the regression tests and the documentation to reflect
this. Remove the UNSAFE_FLOATS #ifdef.
This is only half the story: we still unconditionally reject
floating point operations that result in +/- infinity. See
recent thread on -hackers for more information.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/float.c | 48 | ||||
-rw-r--r-- | src/include/pg_config_manual.h | 8 | ||||
-rw-r--r-- | src/test/regress/expected/float4.out | 30 | ||||
-rw-r--r-- | src/test/regress/expected/float8.out | 30 | ||||
-rw-r--r-- | src/test/regress/sql/float4.sql | 9 | ||||
-rw-r--r-- | src/test/regress/sql/float8.sql | 8 |
6 files changed, 94 insertions, 39 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 2707c83fd62..aed643d862b 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.98 2004/03/11 02:11:13 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.99 2004/03/12 00:25:40 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -114,21 +114,14 @@ static int float8_cmp_internal(float8 a, float8 b); /* - * check to see if a float4 val is outside of - * the FLOAT4_MIN, FLOAT4_MAX bounds. + * check to see if a float4 val is outside of the FLOAT4_MIN, + * FLOAT4_MAX bounds. * - * raise an ereport warning if it is -*/ + * raise an ereport() error if it is + */ static void CheckFloat4Val(double val) { - /* - * defining unsafe floats's will make float4 and float8 ops faster at - * the cost of safety, of course! - */ -#ifdef UNSAFE_FLOATS - return; -#else if (fabs(val) > FLOAT4_MAX) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), @@ -137,27 +130,17 @@ CheckFloat4Val(double val) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("type \"real\" value out of range: underflow"))); - - return; -#endif /* UNSAFE_FLOATS */ } /* - * check to see if a float8 val is outside of - * the FLOAT8_MIN, FLOAT8_MAX bounds. + * check to see if a float8 val is outside of the FLOAT8_MIN, + * FLOAT8_MAX bounds. * - * raise an ereport error if it is + * raise an ereport() error if it is */ static void CheckFloat8Val(double val) { - /* - * defining unsafe floats's will make float4 and float8 ops faster at - * the cost of safety, of course! - */ -#ifdef UNSAFE_FLOATS - return; -#else if (fabs(val) > FLOAT8_MAX) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), @@ -166,7 +149,6 @@ CheckFloat8Val(double val) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("type \"double precision\" value out of range: underflow"))); -#endif /* UNSAFE_FLOATS */ } /* @@ -201,10 +183,6 @@ float4in(PG_FUNCTION_ARGS) * empty strings, but emit a warning noting that the feature * is deprecated. In 7.6+, the warning should be replaced by * an error. - * - * XXX we should accept "Infinity" and "-Infinity" too, but - * what are the correct values to assign? HUGE_VAL will - * provoke an error from CheckFloat4Val. */ if (*num == '\0') { @@ -217,6 +195,10 @@ float4in(PG_FUNCTION_ARGS) } else if (strcasecmp(num, "NaN") == 0) val = NAN; + else if (strcasecmp(num, "Infinity") == 0) + val = HUGE_VAL; + else if (strcasecmp(num, "-Infinity") == 0) + val = -HUGE_VAL; else ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), @@ -239,7 +221,8 @@ float4in(PG_FUNCTION_ARGS) * if we get here, we have a legal double, still need to check to see * if it's a legal float */ - CheckFloat4Val(val); + if (!isinf(val)) + CheckFloat4Val(val); PG_RETURN_FLOAT4((float4) val); } @@ -364,7 +347,8 @@ float8in(PG_FUNCTION_ARGS) errmsg("invalid input syntax for type double precision: \"%s\"", num))); - CheckFloat8Val(val); + if (!isinf(val)) + CheckFloat8Val(val); PG_RETURN_FLOAT8(val); } diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index 8226c6d5cf7..6fcf38ec7b1 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -6,7 +6,7 @@ * for developers. If you edit any of these, be sure to do a *full* * rebuild (and an initdb if noted). * - * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.10 2004/02/11 22:55:26 tgl Exp $ + * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.11 2004/03/12 00:25:40 neilc Exp $ *------------------------------------------------------------------------ */ @@ -176,12 +176,6 @@ #define DEFAULT_PGSOCKET_DIR "/tmp" /* - * Defining this will make float4 and float8 operations faster by - * suppressing overflow/underflow checks. - */ -/* #define UNSAFE_FLOATS */ - -/* * The random() function is expected to yield values between 0 and * MAX_RANDOM_VALUE. Currently, all known implementations yield * 0..2^31-1, so we just hardwire this constant. We could do a diff --git a/src/test/regress/expected/float4.out b/src/test/regress/expected/float4.out index 124b7c378c6..e4d460359fe 100644 --- a/src/test/regress/expected/float4.out +++ b/src/test/regress/expected/float4.out @@ -50,9 +50,39 @@ SELECT ' NAN '::float4; NaN (1 row) +SELECT 'infinity'::float4; + float4 +---------- + Infinity +(1 row) + +SELECT ' -INFINiTY '::float4; + float4 +----------- + -Infinity +(1 row) + -- bad special inputs SELECT 'N A N'::float4; ERROR: invalid input syntax for type real: "N A N" +SELECT 'NaN x'::float4; +ERROR: invalid input syntax for type real: "NaN x" +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? +---------- + NaN +(1 row) + +SELECT 'nan'::float4 / 'nan'::float4; + ?column? +---------- + NaN +(1 row) + SELECT '' AS five, FLOAT4_TBL.*; five | f1 ------+------------- diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out index 89e2bbf9025..798a67c04fe 100644 --- a/src/test/regress/expected/float8.out +++ b/src/test/regress/expected/float8.out @@ -50,9 +50,39 @@ SELECT ' NAN '::float8; NaN (1 row) +SELECT 'infinity'::float8; + float8 +---------- + Infinity +(1 row) + +SELECT ' -INFINiTY '::float8; + float8 +----------- + -Infinity +(1 row) + -- bad special inputs SELECT 'N A N'::float8; ERROR: invalid input syntax for type double precision: "N A N" +SELECT 'NaN x'::float8; +ERROR: invalid input syntax for type double precision: "NaN x" +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? +---------- + NaN +(1 row) + +SELECT 'nan'::float8 / 'nan'::float8; + ?column? +---------- + NaN +(1 row) + SELECT '' AS five, FLOAT8_TBL.*; five | f1 ------+---------------------- diff --git a/src/test/regress/sql/float4.sql b/src/test/regress/sql/float4.sql index b7b64f2e50e..a7147409ec9 100644 --- a/src/test/regress/sql/float4.sql +++ b/src/test/regress/sql/float4.sql @@ -29,8 +29,17 @@ INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5'); SELECT 'NaN'::float4; SELECT 'nan'::float4; SELECT ' NAN '::float4; +SELECT 'infinity'::float4; +SELECT ' -INFINiTY '::float4; -- bad special inputs SELECT 'N A N'::float4; +SELECT 'NaN x'::float4; +SELECT ' INFINITY x'::float4; + +SELECT 'Infinity'::float4 + 100.0; +SELECT 'Infinity'::float4 / 'Infinity'::float4; +SELECT 'nan'::float4 / 'nan'::float4; + SELECT '' AS five, FLOAT4_TBL.*; diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql index 1e5e8ad4302..593df68a326 100644 --- a/src/test/regress/sql/float8.sql +++ b/src/test/regress/sql/float8.sql @@ -29,8 +29,16 @@ INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5'); SELECT 'NaN'::float8; SELECT 'nan'::float8; SELECT ' NAN '::float8; +SELECT 'infinity'::float8; +SELECT ' -INFINiTY '::float8; -- bad special inputs SELECT 'N A N'::float8; +SELECT 'NaN x'::float8; +SELECT ' INFINITY x'::float8; + +SELECT 'Infinity'::float8 + 100.0; +SELECT 'Infinity'::float8 / 'Infinity'::float8; +SELECT 'nan'::float8 / 'nan'::float8; SELECT '' AS five, FLOAT8_TBL.*; |