]> granicus.if.org Git - postgresql/commitdiff
Fix numeric_smaller, numeric_larger, float4smaller, float4larger,
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 30 Jul 2003 19:48:41 +0000 (19:48 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 30 Jul 2003 19:48:41 +0000 (19:48 +0000)
float8smaller, float8larger (and thereby the MIN/MAX aggregates on these
datatypes) to agree with the datatypes' comparison operations as
regards NaN handling.  In all these datatypes, NaN is arbitrarily
considered larger than any normal value ... but MIN/MAX had not gotten
the word.  Per recent discussion on pgsql-sql.

src/backend/utils/adt/float.c
src/backend/utils/adt/numeric.c

index ac3fb2d149a79a7292a1587b62f278d89685fd80..9ef2e80da760204e3af535e5a5ddc6dd6190c2af 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.90 2003/07/27 04:53:05 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.91 2003/07/30 19:48:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -109,6 +109,8 @@ int         extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
 
 static void CheckFloat4Val(double val);
 static void CheckFloat8Val(double val);
+static int float4_cmp_internal(float4 a, float4 b);
+static int float8_cmp_internal(float8 a, float8 b);
 
 
 /*
@@ -413,7 +415,10 @@ float4larger(PG_FUNCTION_ARGS)
        float4          arg2 = PG_GETARG_FLOAT4(1);
        float4          result;
 
-       result = ((arg1 > arg2) ? arg1 : arg2);
+       if (float4_cmp_internal(arg1, arg2) > 0)
+               result = arg1;
+       else
+               result = arg2;
        PG_RETURN_FLOAT4(result);
 }
 
@@ -424,7 +429,10 @@ float4smaller(PG_FUNCTION_ARGS)
        float4          arg2 = PG_GETARG_FLOAT4(1);
        float4          result;
 
-       result = ((arg1 < arg2) ? arg1 : arg2);
+       if (float4_cmp_internal(arg1, arg2) < 0)
+               result = arg1;
+       else
+               result = arg2;
        PG_RETURN_FLOAT4(result);
 }
 
@@ -480,8 +488,10 @@ float8larger(PG_FUNCTION_ARGS)
        float8          arg2 = PG_GETARG_FLOAT8(1);
        float8          result;
 
-       result = ((arg1 > arg2) ? arg1 : arg2);
-
+       if (float8_cmp_internal(arg1, arg2) > 0)
+               result = arg1;
+       else
+               result = arg2;
        PG_RETURN_FLOAT8(result);
 }
 
@@ -492,8 +502,10 @@ float8smaller(PG_FUNCTION_ARGS)
        float8          arg2 = PG_GETARG_FLOAT8(1);
        float8          result;
 
-       result = ((arg1 < arg2) ? arg1 : arg2);
-
+       if (float8_cmp_internal(arg1, arg2) < 0)
+               result = arg1;
+       else
+               result = arg2;
        PG_RETURN_FLOAT8(result);
 }
 
index 476d3d5b5ce5f84bfdd5e31c87a2734380b91e4c..4f5029a26c1b32d406d92b7e6fbfc1a606700dcf 100644 (file)
@@ -14,7 +14,7 @@
  * Copyright (c) 1998-2003, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.63 2003/07/27 04:53:07 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.64 2003/07/30 19:48:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -316,7 +316,7 @@ numeric_in(PG_FUNCTION_ARGS)
        /*
         * Check for NaN
         */
-       if (strcmp(str, "NaN") == 0)
+       if (strcasecmp(str, "NaN") == 0)
                PG_RETURN_NUMERIC(make_result(&const_nan));
 
        /*
@@ -1239,34 +1239,15 @@ numeric_smaller(PG_FUNCTION_ARGS)
 {
        Numeric         num1 = PG_GETARG_NUMERIC(0);
        Numeric         num2 = PG_GETARG_NUMERIC(1);
-       NumericVar      arg1;
-       NumericVar      arg2;
-       Numeric         res;
-
-       /*
-        * Handle NaN
-        */
-       if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-               PG_RETURN_NUMERIC(make_result(&const_nan));
 
        /*
-        * Unpack the values, and decide which is the smaller one
+        * Use cmp_numerics so that this will agree with the comparison
+        * operators, particularly as regards comparisons involving NaN.
         */
-       init_var(&arg1);
-       init_var(&arg2);
-
-       set_var_from_num(num1, &arg1);
-       set_var_from_num(num2, &arg2);
-
-       if (cmp_var(&arg1, &arg2) <= 0)
-               res = make_result(&arg1);
+       if (cmp_numerics(num1, num2) < 0)
+               PG_RETURN_NUMERIC(num1);
        else
-               res = make_result(&arg2);
-
-       free_var(&arg1);
-       free_var(&arg2);
-
-       PG_RETURN_NUMERIC(res);
+               PG_RETURN_NUMERIC(num2);
 }
 
 
@@ -1280,34 +1261,15 @@ numeric_larger(PG_FUNCTION_ARGS)
 {
        Numeric         num1 = PG_GETARG_NUMERIC(0);
        Numeric         num2 = PG_GETARG_NUMERIC(1);
-       NumericVar      arg1;
-       NumericVar      arg2;
-       Numeric         res;
-
-       /*
-        * Handle NaN
-        */
-       if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-               PG_RETURN_NUMERIC(make_result(&const_nan));
 
        /*
-        * Unpack the values, and decide which is the larger one
+        * Use cmp_numerics so that this will agree with the comparison
+        * operators, particularly as regards comparisons involving NaN.
         */
-       init_var(&arg1);
-       init_var(&arg2);
-
-       set_var_from_num(num1, &arg1);
-       set_var_from_num(num2, &arg2);
-
-       if (cmp_var(&arg1, &arg2) >= 0)
-               res = make_result(&arg1);
+       if (cmp_numerics(num1, num2) > 0)
+               PG_RETURN_NUMERIC(num1);
        else
-               res = make_result(&arg2);
-
-       free_var(&arg1);
-       free_var(&arg2);
-
-       PG_RETURN_NUMERIC(res);
+               PG_RETURN_NUMERIC(num2);
 }