On Wed, Dec 21, 2011 at 18:21, Marti Raudsepp <ma...@juffo.org> wrote: > I think the least invasive fix, as proposed by Jeroen, is to fail only > when ERANGE is set *and* the return value is 0.0 or +/-HUGE_VAL. > Reading relevant specifications, this seems to be a fairly safe > assumption. That's what the attached patch does.
Oops, now attached the patch too. Regards, Marti
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c new file mode 100644 index 63b09a4..86e1661 *** a/src/backend/utils/adt/float.c --- b/src/backend/utils/adt/float.c *************** float4in(PG_FUNCTION_ARGS) *** 238,247 **** endptr = num + 9; } else if (errno == ERANGE) ! ereport(ERROR, ! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), ! errmsg("\"%s\" is out of range for type real", ! orig_num))); else ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), --- 238,257 ---- endptr = num + 9; } else if (errno == ERANGE) ! { ! /* ! * We only fail for ERANGE if the return value is also out of ! * range. Some platforms parse and return denormal values ! * correctly, but still set errno to ERANGE. ! */ ! if (val == 0.0 || val == HUGE_VAL || val == -HUGE_VAL) ! { ! ereport(ERROR, ! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), ! errmsg("\"%s\" is out of range for type real", ! orig_num))); ! } ! } else ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), *************** float8in(PG_FUNCTION_ARGS) *** 431,440 **** endptr = num + 9; } else if (errno == ERANGE) ! ereport(ERROR, ! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), ! errmsg("\"%s\" is out of range for type double precision", ! orig_num))); else ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), --- 441,460 ---- endptr = num + 9; } else if (errno == ERANGE) ! { ! /* ! * We only fail for ERANGE if the return value is also out of ! * range. Some platforms parse and return denormal values ! * correctly, but still set errno to ERANGE. ! */ ! if (val == 0.0 || val == HUGE_VAL || val == -HUGE_VAL) ! { ! ereport(ERROR, ! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), ! errmsg("\"%s\" is out of range for type double precision", ! orig_num))); ! } ! } else ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out new file mode 100644 index 6221538..e3fb8d3 *** a/src/test/regress/expected/float8.out --- b/src/test/regress/expected/float8.out *************** SELECT '-10e-400'::float8; *** 24,29 **** --- 24,48 ---- ERROR: "-10e-400" is out of range for type double precision LINE 1: SELECT '-10e-400'::float8; ^ + -- test denormal value parsing + SELECT '4.95e-324'::float8 < '1.49e-323'::float8; + ?column? + ---------- + t + (1 row) + + SELECT '4.95e-324'::float8 > '0'::float8; + ?column? + ---------- + t + (1 row) + + SELECT substr('-4.95e-324'::float8::text, 1, 2); + substr + -------- + -4 + (1 row) + -- bad input INSERT INTO FLOAT8_TBL(f1) VALUES (''); ERROR: invalid input syntax for type double precision: "" diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql new file mode 100644 index 92a574a..e13eb51 *** a/src/test/regress/sql/float8.sql --- b/src/test/regress/sql/float8.sql *************** SELECT '-10e400'::float8; *** 16,21 **** --- 16,26 ---- SELECT '10e-400'::float8; SELECT '-10e-400'::float8; + -- test denormal value parsing + SELECT '4.95e-324'::float8 < '1.49e-323'::float8; + SELECT '4.95e-324'::float8 > '0'::float8; + SELECT substr('-4.95e-324'::float8::text, 1, 2); + -- bad input INSERT INTO FLOAT8_TBL(f1) VALUES (''); INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers