Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4b1c669

Browse files
committed
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.
1 parent 0159f7f commit 4b1c669

File tree

2 files changed

+31
-57
lines changed

2 files changed

+31
-57
lines changed

src/backend/utils/adt/float.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.90 2003/07/27 04:53:05 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.91 2003/07/30 19:48:38 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -109,6 +109,8 @@ int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
109109

110110
static void CheckFloat4Val(double val);
111111
static void CheckFloat8Val(double val);
112+
static int float4_cmp_internal(float4 a, float4 b);
113+
static int float8_cmp_internal(float8 a, float8 b);
112114

113115

114116
/*
@@ -413,7 +415,10 @@ float4larger(PG_FUNCTION_ARGS)
413415
float4 arg2 = PG_GETARG_FLOAT4(1);
414416
float4 result;
415417

416-
result = ((arg1 > arg2) ? arg1 : arg2);
418+
if (float4_cmp_internal(arg1, arg2) > 0)
419+
result = arg1;
420+
else
421+
result = arg2;
417422
PG_RETURN_FLOAT4(result);
418423
}
419424

@@ -424,7 +429,10 @@ float4smaller(PG_FUNCTION_ARGS)
424429
float4 arg2 = PG_GETARG_FLOAT4(1);
425430
float4 result;
426431

427-
result = ((arg1 < arg2) ? arg1 : arg2);
432+
if (float4_cmp_internal(arg1, arg2) < 0)
433+
result = arg1;
434+
else
435+
result = arg2;
428436
PG_RETURN_FLOAT4(result);
429437
}
430438

@@ -480,8 +488,10 @@ float8larger(PG_FUNCTION_ARGS)
480488
float8 arg2 = PG_GETARG_FLOAT8(1);
481489
float8 result;
482490

483-
result = ((arg1 > arg2) ? arg1 : arg2);
484-
491+
if (float8_cmp_internal(arg1, arg2) > 0)
492+
result = arg1;
493+
else
494+
result = arg2;
485495
PG_RETURN_FLOAT8(result);
486496
}
487497

@@ -492,8 +502,10 @@ float8smaller(PG_FUNCTION_ARGS)
492502
float8 arg2 = PG_GETARG_FLOAT8(1);
493503
float8 result;
494504

495-
result = ((arg1 < arg2) ? arg1 : arg2);
496-
505+
if (float8_cmp_internal(arg1, arg2) < 0)
506+
result = arg1;
507+
else
508+
result = arg2;
497509
PG_RETURN_FLOAT8(result);
498510
}
499511

src/backend/utils/adt/numeric.c

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Copyright (c) 1998-2003, PostgreSQL Global Development Group
1515
*
1616
* IDENTIFICATION
17-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.63 2003/07/27 04:53:07 tgl Exp $
17+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.64 2003/07/30 19:48:41 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -316,7 +316,7 @@ numeric_in(PG_FUNCTION_ARGS)
316316
/*
317317
* Check for NaN
318318
*/
319-
if (strcmp(str, "NaN") == 0)
319+
if (strcasecmp(str, "NaN") == 0)
320320
PG_RETURN_NUMERIC(make_result(&const_nan));
321321

322322
/*
@@ -1239,34 +1239,15 @@ numeric_smaller(PG_FUNCTION_ARGS)
12391239
{
12401240
Numeric num1 = PG_GETARG_NUMERIC(0);
12411241
Numeric num2 = PG_GETARG_NUMERIC(1);
1242-
NumericVar arg1;
1243-
NumericVar arg2;
1244-
Numeric res;
1245-
1246-
/*
1247-
* Handle NaN
1248-
*/
1249-
if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1250-
PG_RETURN_NUMERIC(make_result(&const_nan));
12511242

12521243
/*
1253-
* Unpack the values, and decide which is the smaller one
1244+
* Use cmp_numerics so that this will agree with the comparison
1245+
* operators, particularly as regards comparisons involving NaN.
12541246
*/
1255-
init_var(&arg1);
1256-
init_var(&arg2);
1257-
1258-
set_var_from_num(num1, &arg1);
1259-
set_var_from_num(num2, &arg2);
1260-
1261-
if (cmp_var(&arg1, &arg2) <= 0)
1262-
res = make_result(&arg1);
1247+
if (cmp_numerics(num1, num2) < 0)
1248+
PG_RETURN_NUMERIC(num1);
12631249
else
1264-
res = make_result(&arg2);
1265-
1266-
free_var(&arg1);
1267-
free_var(&arg2);
1268-
1269-
PG_RETURN_NUMERIC(res);
1250+
PG_RETURN_NUMERIC(num2);
12701251
}
12711252

12721253

@@ -1280,34 +1261,15 @@ numeric_larger(PG_FUNCTION_ARGS)
12801261
{
12811262
Numeric num1 = PG_GETARG_NUMERIC(0);
12821263
Numeric num2 = PG_GETARG_NUMERIC(1);
1283-
NumericVar arg1;
1284-
NumericVar arg2;
1285-
Numeric res;
1286-
1287-
/*
1288-
* Handle NaN
1289-
*/
1290-
if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1291-
PG_RETURN_NUMERIC(make_result(&const_nan));
12921264

12931265
/*
1294-
* Unpack the values, and decide which is the larger one
1266+
* Use cmp_numerics so that this will agree with the comparison
1267+
* operators, particularly as regards comparisons involving NaN.
12951268
*/
1296-
init_var(&arg1);
1297-
init_var(&arg2);
1298-
1299-
set_var_from_num(num1, &arg1);
1300-
set_var_from_num(num2, &arg2);
1301-
1302-
if (cmp_var(&arg1, &arg2) >= 0)
1303-
res = make_result(&arg1);
1269+
if (cmp_numerics(num1, num2) > 0)
1270+
PG_RETURN_NUMERIC(num1);
13041271
else
1305-
res = make_result(&arg2);
1306-
1307-
free_var(&arg1);
1308-
free_var(&arg2);
1309-
1310-
PG_RETURN_NUMERIC(res);
1272+
PG_RETURN_NUMERIC(num2);
13111273
}
13121274

13131275

0 commit comments

Comments
 (0)