On Wed, Dec 21, 2011 at 18:21, Marti Raudsepp <[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers