/* did we not see anything that looks like a double? */
if (endptr == num || errno != 0)
{
+ int save_errno = errno;
+
/*
* C99 requires that strtod() accept NaN and [-]Infinity, but not all
* platforms support that yet (and some accept them but set ERANGE
val = -get_float4_infinity();
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 if (save_errno == ERANGE)
+ {
+ /*
+ * Some platforms return ERANGE for denormalized numbers (those
+ * that are not zero, but are too close to zero to have full
+ * precision). We'd prefer not to throw error for that, so try
+ * to detect whether it's a "real" out-of-range condition by
+ * checking to see if the result is zero or huge.
+ */
+ 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),
/* did we not see anything that looks like a double? */
if (endptr == num || errno != 0)
{
+ int save_errno = errno;
+
/*
* C99 requires that strtod() accept NaN and [-]Infinity, but not all
* platforms support that yet (and some accept them but set ERANGE
val = -get_float8_infinity();
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 if (save_errno == ERANGE)
+ {
+ /*
+ * Some platforms return ERANGE for denormalized numbers (those
+ * that are not zero, but are too close to zero to have full
+ * precision). We'd prefer not to throw error for that, so try
+ * to detect whether it's a "real" out-of-range condition by
+ * checking to see if the result is zero or huge.
+ */
+ 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),