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

Reply via email to