mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Fix numeric_smaller, numeric_larger, float4smaller, float4larger,
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.
This commit is contained in:
parent
0159f7f272
commit
4b1c6695f1
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 CheckFloat4Val(double val);
|
||||||
static void CheckFloat8Val(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 arg2 = PG_GETARG_FLOAT4(1);
|
||||||
float4 result;
|
float4 result;
|
||||||
|
|
||||||
result = ((arg1 > arg2) ? arg1 : arg2);
|
if (float4_cmp_internal(arg1, arg2) > 0)
|
||||||
|
result = arg1;
|
||||||
|
else
|
||||||
|
result = arg2;
|
||||||
PG_RETURN_FLOAT4(result);
|
PG_RETURN_FLOAT4(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +429,10 @@ float4smaller(PG_FUNCTION_ARGS)
|
|||||||
float4 arg2 = PG_GETARG_FLOAT4(1);
|
float4 arg2 = PG_GETARG_FLOAT4(1);
|
||||||
float4 result;
|
float4 result;
|
||||||
|
|
||||||
result = ((arg1 < arg2) ? arg1 : arg2);
|
if (float4_cmp_internal(arg1, arg2) < 0)
|
||||||
|
result = arg1;
|
||||||
|
else
|
||||||
|
result = arg2;
|
||||||
PG_RETURN_FLOAT4(result);
|
PG_RETURN_FLOAT4(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,8 +488,10 @@ float8larger(PG_FUNCTION_ARGS)
|
|||||||
float8 arg2 = PG_GETARG_FLOAT8(1);
|
float8 arg2 = PG_GETARG_FLOAT8(1);
|
||||||
float8 result;
|
float8 result;
|
||||||
|
|
||||||
result = ((arg1 > arg2) ? arg1 : arg2);
|
if (float8_cmp_internal(arg1, arg2) > 0)
|
||||||
|
result = arg1;
|
||||||
|
else
|
||||||
|
result = arg2;
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,8 +502,10 @@ float8smaller(PG_FUNCTION_ARGS)
|
|||||||
float8 arg2 = PG_GETARG_FLOAT8(1);
|
float8 arg2 = PG_GETARG_FLOAT8(1);
|
||||||
float8 result;
|
float8 result;
|
||||||
|
|
||||||
result = ((arg1 < arg2) ? arg1 : arg2);
|
if (float8_cmp_internal(arg1, arg2) < 0)
|
||||||
|
result = arg1;
|
||||||
|
else
|
||||||
|
result = arg2;
|
||||||
PG_RETURN_FLOAT8(result);
|
PG_RETURN_FLOAT8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* Copyright (c) 1998-2003, PostgreSQL Global Development Group
|
* Copyright (c) 1998-2003, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* Check for NaN
|
||||||
*/
|
*/
|
||||||
if (strcmp(str, "NaN") == 0)
|
if (strcasecmp(str, "NaN") == 0)
|
||||||
PG_RETURN_NUMERIC(make_result(&const_nan));
|
PG_RETURN_NUMERIC(make_result(&const_nan));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1239,34 +1239,15 @@ numeric_smaller(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
Numeric num1 = PG_GETARG_NUMERIC(0);
|
Numeric num1 = PG_GETARG_NUMERIC(0);
|
||||||
Numeric num2 = PG_GETARG_NUMERIC(1);
|
Numeric num2 = PG_GETARG_NUMERIC(1);
|
||||||
NumericVar arg1;
|
|
||||||
NumericVar arg2;
|
|
||||||
Numeric res;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle NaN
|
* Use cmp_numerics so that this will agree with the comparison
|
||||||
|
* operators, particularly as regards comparisons involving NaN.
|
||||||
*/
|
*/
|
||||||
if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
|
if (cmp_numerics(num1, num2) < 0)
|
||||||
PG_RETURN_NUMERIC(make_result(&const_nan));
|
PG_RETURN_NUMERIC(num1);
|
||||||
|
|
||||||
/*
|
|
||||||
* Unpack the values, and decide which is the smaller one
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
else
|
else
|
||||||
res = make_result(&arg2);
|
PG_RETURN_NUMERIC(num2);
|
||||||
|
|
||||||
free_var(&arg1);
|
|
||||||
free_var(&arg2);
|
|
||||||
|
|
||||||
PG_RETURN_NUMERIC(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1280,34 +1261,15 @@ numeric_larger(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
Numeric num1 = PG_GETARG_NUMERIC(0);
|
Numeric num1 = PG_GETARG_NUMERIC(0);
|
||||||
Numeric num2 = PG_GETARG_NUMERIC(1);
|
Numeric num2 = PG_GETARG_NUMERIC(1);
|
||||||
NumericVar arg1;
|
|
||||||
NumericVar arg2;
|
|
||||||
Numeric res;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle NaN
|
* Use cmp_numerics so that this will agree with the comparison
|
||||||
|
* operators, particularly as regards comparisons involving NaN.
|
||||||
*/
|
*/
|
||||||
if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
|
if (cmp_numerics(num1, num2) > 0)
|
||||||
PG_RETURN_NUMERIC(make_result(&const_nan));
|
PG_RETURN_NUMERIC(num1);
|
||||||
|
|
||||||
/*
|
|
||||||
* Unpack the values, and decide which is the larger one
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
else
|
else
|
||||||
res = make_result(&arg2);
|
PG_RETURN_NUMERIC(num2);
|
||||||
|
|
||||||
free_var(&arg1);
|
|
||||||
free_var(&arg2);
|
|
||||||
|
|
||||||
PG_RETURN_NUMERIC(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user