Skip to content

Commit cb3e9e4

Browse files
committed
Put in_range_float4_float8's work in-line.
In commit 8b29e88, I'd dithered about whether to make in_range_float4_float8 be a standalone copy of the float in-range logic or have it punt to in_range_float8_float8. I went with the latter, which saves code space though at the cost of performance and readability. However, it emerges that this tickles a compiler or hardware bug on buildfarm member opossum. Test results from commit 55e0e45 show conclusively that widening a float4 NaN to float8 produces Inf, not NaN, on that machine; which accounts perfectly for the window RANGE test failures it's been showing. We can dodge this problem by making in_range_float4_float8 be an independent function, so that it checks for NaN inputs before widening them. Ordinarily I'd not be very excited about working around such obviously broken functionality; but given that this was a judgment call to begin with, I don't mind reversing it.
1 parent 2f52518 commit cb3e9e4

File tree

1 file changed

+58
-10
lines changed

1 file changed

+58
-10
lines changed

src/backend/utils/adt/float.c

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,16 +1254,64 @@ in_range_float8_float8(PG_FUNCTION_ARGS)
12541254
Datum
12551255
in_range_float4_float8(PG_FUNCTION_ARGS)
12561256
{
1257-
/* Doesn't seem worth duplicating code for, so just invoke float8_float8 */
1258-
float8 val = (float8) PG_GETARG_FLOAT4(0);
1259-
float8 base = (float8) PG_GETARG_FLOAT4(1);
1260-
1261-
return DirectFunctionCall5(in_range_float8_float8,
1262-
Float8GetDatumFast(val),
1263-
Float8GetDatumFast(base),
1264-
PG_GETARG_DATUM(2),
1265-
PG_GETARG_DATUM(3),
1266-
PG_GETARG_DATUM(4));
1257+
float4 val = PG_GETARG_FLOAT4(0);
1258+
float4 base = PG_GETARG_FLOAT4(1);
1259+
float8 offset = PG_GETARG_FLOAT8(2);
1260+
bool sub = PG_GETARG_BOOL(3);
1261+
bool less = PG_GETARG_BOOL(4);
1262+
float8 sum;
1263+
1264+
/*
1265+
* Reject negative or NaN offset. Negative is per spec, and NaN is
1266+
* because appropriate semantics for that seem non-obvious.
1267+
*/
1268+
if (isnan(offset) || offset < 0)
1269+
ereport(ERROR,
1270+
(errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE),
1271+
errmsg("invalid preceding or following size in window function")));
1272+
1273+
/*
1274+
* Deal with cases where val and/or base is NaN, following the rule that
1275+
* NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1276+
* affect the conclusion.
1277+
*/
1278+
if (isnan(val))
1279+
{
1280+
if (isnan(base))
1281+
PG_RETURN_BOOL(true); /* NAN = NAN */
1282+
else
1283+
PG_RETURN_BOOL(!less); /* NAN > non-NAN */
1284+
}
1285+
else if (isnan(base))
1286+
{
1287+
PG_RETURN_BOOL(less); /* non-NAN < NAN */
1288+
}
1289+
1290+
/*
1291+
* Deal with infinite offset (necessarily +inf, at this point). We must
1292+
* special-case this because if base happens to be -inf, their sum would
1293+
* be NaN, which is an overflow-ish condition we should avoid.
1294+
*/
1295+
if (isinf(offset))
1296+
{
1297+
PG_RETURN_BOOL(sub ? !less : less);
1298+
}
1299+
1300+
/*
1301+
* Otherwise it should be safe to compute base +/- offset. We trust the
1302+
* FPU to cope if base is +/-inf or the true sum would overflow, and
1303+
* produce a suitably signed infinity, which will compare properly against
1304+
* val whether or not that's infinity.
1305+
*/
1306+
if (sub)
1307+
sum = base - offset;
1308+
else
1309+
sum = base + offset;
1310+
1311+
if (less)
1312+
PG_RETURN_BOOL(val <= sum);
1313+
else
1314+
PG_RETURN_BOOL(val >= sum);
12671315
}
12681316

12691317

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy