[HACKERS] Regression failure for floats

2004-03-13 Thread Bruce Momjian
I am seeing the following regression failure for current CVS.  On my OS,
BSD/OS 4.3, it seems once you hit Infinity, you can't negate it. 
/usr/include/math.h has:

/* Generate an overflow to create +Inf; the multiply shuts up gcc 1 */
#define HUGE_VAL(1e250*1e250)   /* IEEE: positive infinity */

and our float4in code has:

else if (strcasecmp(num, -Infinity) == 0)
val = -HUGE_VAL;

Seems that doesn't work for me.

---

*** ./expected/float4.out   Sat Mar 13 23:07:10 2004
--- ./results/float4.outSat Mar 13 23:10:30 2004
***
*** 58,65 
  
  SELECT '  -INFINiTY   '::float4;
float4   
! ---
!  -Infinity
  (1 row)
  
  -- bad special inputs
--- 58,65 
  
  SELECT '  -INFINiTY   '::float4;
float4  
! --
!  Infinity
  (1 row)
  
  -- bad special inputs

==

*** ./expected/float8.out   Sat Mar 13 23:07:10 2004
--- ./results/float8.outSat Mar 13 23:10:30 2004
***
*** 58,65 
  
  SELECT '  -INFINiTY   '::float8;
float8   
! ---
!  -Infinity
  (1 row)
  
  -- bad special inputs
--- 58,65 
  
  SELECT '  -INFINiTY   '::float8;
float8  
! --
!  Infinity
  (1 row)
  
  -- bad special inputs



-- 
  Bruce Momjian|  http://candle.pha.pa.us
  [EMAIL PROTECTED]   |  (610) 359-1001
  +  If your life is a hard drive, |  13 Roberts Road
  +  Christ can be your backup.|  Newtown Square, Pennsylvania 19073

---(end of broadcast)---
TIP 4: Don't 'kill -9' the postmaster


Re: [HACKERS] Regression failure for floats

2004-03-13 Thread Neil Conway
Bruce Momjian [EMAIL PROTECTED] writes:
 I am seeing the following regression failure for current CVS.  On my
 OS, BSD/OS 4.3, it seems once you hit Infinity, you can't negate it.

Actually, I suspect the problem is that isinf() on your platform
returns 1 for any infinity (rather than -1 for negative infinity and 1
for positive infinity). Some existing code in float4out() and
float8out() assumed that a positive return from isinf() indicated a
positive infinity, which is not per C99.

Anyway, Tom and I worked through this issue, and a couple other
portability problems with the recent float changes, via private
email. The current patch is attached -- Tom hasn't yet gotten back to
me on whether this fixes the problem for him on HPUX, but it fixes my
OS X box.

-Neil

Index: src/backend/utils/adt/float.c
===
RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/float.c,v
retrieving revision 1.99
diff -c -r1.99 float.c
*** a/src/backend/utils/adt/float.c	12 Mar 2004 00:25:40 -	1.99
--- b/src/backend/utils/adt/float.c	14 Mar 2004 01:07:21 -
***
*** 109,117 
--- 109,138 
  
  static void CheckFloat4Val(double val);
  static void CheckFloat8Val(double val);
+ static int	is_infinite(double val);
  static int	float4_cmp_internal(float4 a, float4 b);
  static int	float8_cmp_internal(float8 a, float8 b);
  
+ /*
+  * Returns -1 if 'val' represents negative infinity, 1 if 'val'
+  * represents (positive) infinity, and 0 otherwise. On same platforms,
+  * this is equivalent to the isinf() macro, but not everywhere: C99
+  * does not specify that isinf() needs to distinguish between positive
+  * and negative infinity.
+  */
+ static int
+ is_infinite(double val)
+ {
+ 	int inf = isinf(val);
+ 
+ 	if (inf == 0)
+ 		return 0;
+ 
+ 	if (val  0)
+ 		return 1;
+ 
+ 	return -1;
+ }
  
  /*
   * check to see if a float4 val is outside of the FLOAT4_MIN,
***
*** 154,160 
  /*
   *		float4in		- converts num to float
   *		  restricted syntax:
!  *		  {sp} [+|-] {digit} [.{digit}] [exp]
   *		  where sp is a space, digit is 0-9,
   *		  exp is e or E followed by an integer.
   */
--- 175,182 
  /*
   *		float4in		- converts num to float
   *		  restricted syntax:
!  *		
!   {sp} [+|-] {digit} [.{digit}] [exp]
   *		  where sp is a space, digit is 0-9,
   *		  exp is e or E followed by an integer.
   */
***
*** 162,209 
  float4in(PG_FUNCTION_ARGS)
  {
  	char	   *num = PG_GETARG_CSTRING(0);
  	double		val;
  	char	   *endptr;
  
  	errno = 0;
  	val = strtod(num, endptr);
  
  	if (errno == ERANGE)
  		ereport(ERROR,
  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
!  errmsg(\%s\ is out of range for type real, num)));
  
  	if (num == endptr)
  	{
  		/*
! 		 * We didn't find anything that looks like a float in the input
! 		 *
! 		 * In releases prior to 7.5, we accepted an empty string as
! 		 * valid input (yielding a float8 of 0). In 7.5, we accept
! 		 * empty strings, but emit a warning noting that the feature
! 		 * is deprecated. In 7.6+, the warning should be replaced by
! 		 * an error.
  		 */
! 		if (*num == '\0')
  		{
- 			ereport(WARNING,
- 	(errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
- 	 errmsg(deprecated input syntax for type real: \\),
- 	 errdetail(This input will be rejected in 
- 			   a future release of PostgreSQL.)));
- 			Assert(val == 0.0);
- 		}
- 		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),
  	 errmsg(invalid input syntax for type real: \%s\,
! 			num)));
  	}
  
  	/* skip trailing whitespace */
--- 184,261 
  float4in(PG_FUNCTION_ARGS)
  {
  	char	   *num = PG_GETARG_CSTRING(0);
+ 	char	   *orig_num;
  	double		val;
  	char	   *endptr;
  
+ 	/*
+ 	 * endptr points to the first character _after_ the sequence we
+ 	 * recognized as a valid floating point number. orig_num points to
+ 	 * the original input string.
+ 	 */
+ 	orig_num = num;
+ 
+ 	/*
+ 	 * Check for an empty-string input to begin with, to avoid
+ 	 * the vagaries of strtod() on different platforms.
+ 	 *
+ 	 * In releases prior to 7.5, we accepted an empty string as valid
+ 	 * input (yielding a float4 of 0). In 7.5, we accept empty
+ 	 * strings, but emit a warning noting that the feature is
+ 	 * deprecated. In 7.6+, the warning should be replaced by an
+ 	 * error.
+ 	 */
+ 	if (*num == '\0')
+ 	{
+ 		ereport(WARNING,
+ (errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
+  errmsg(deprecated input syntax for type real: \\),
+  errdetail(This input will be rejected in 
+ 		   a future release of PostgreSQL.)));
+ 		PG_RETURN_FLOAT4((float4) 0.0);
+ 	}
+ 
+ 	/* skip leading whitespace */
+ 	while (*num != 

Re: [HACKERS] Regression failure for floats

2004-03-13 Thread Tom Lane
Bruce Momjian [EMAIL PROTECTED] writes:
 I am seeing the following regression failure for current CVS.  On my OS,
 BSD/OS 4.3, it seems once you hit Infinity, you can't negate it. 
 /usr/include/math.h has:
   /* Generate an overflow to create +Inf; the multiply shuts up gcc 1 */
   #define HUGE_VAL(1e250*1e250)   /* IEEE: positive infinity */
 and our float4in code has:
 else if (strcasecmp(num, -Infinity) == 0)
 val = -HUGE_VAL;
 Seems that doesn't work for me.

No, the bug is that Neil assumed isinf() would tell him the sign of an
infinity.  I believe he's about to commit a patch for this and some
other bogosities.

regards, tom lane

---(end of broadcast)---
TIP 8: explain analyze is your friend


Re: [HACKERS] Regression failure for floats

2004-03-13 Thread Claudio Natoli


 email. The current patch is attached -- Tom hasn't yet gotten back to
 me on whether this fixes the problem for him on HPUX, but it fixes my
 OS X box.

Fixes issues under win32. Thanks.

Claudio

--- 
Certain disclaimers and policies apply to all email sent from Memetrics.
For the full text of these disclaimers and policies see 
a
href=http://www.memetrics.com/emailpolicy.html;http://www.memetrics.com/em
ailpolicy.html/a

---(end of broadcast)---
TIP 5: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faqs/FAQ.html