Skip to content

Commit 86ffdca

Browse files
committed
Remove the special cases to prevent minus-zero results in float4 and float8
unary minus operators. We weren't attempting to prevent minus zero anywhere else; in view of our gradual trend to make the float datatypes more IEEE standard compliant, we should allow minus zero here rather than disallow it elsewhere. We don't, however, expect that all platforms will produce minus zero, so we need to adjust the one affected regression test to allow both results. Per discussion of bug #4660. (In passing, clean up a couple other minor infelicities in float.c.)
1 parent cdd46c7 commit 86ffdca

File tree

3 files changed

+146
-15
lines changed

3 files changed

+146
-15
lines changed

src/backend/utils/adt/float.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.159 2009/01/01 17:23:49 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.160 2009/02/18 19:23:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -576,9 +576,7 @@ float4um(PG_FUNCTION_ARGS)
576576
float4 arg1 = PG_GETARG_FLOAT4(0);
577577
float4 result;
578578

579-
result = ((arg1 != 0) ? -(arg1) : arg1);
580-
581-
CHECKFLOATVAL(result, isinf(arg1), true);
579+
result = -arg1;
582580
PG_RETURN_FLOAT4(result);
583581
}
584582

@@ -645,9 +643,7 @@ float8um(PG_FUNCTION_ARGS)
645643
float8 arg1 = PG_GETARG_FLOAT8(0);
646644
float8 result;
647645

648-
result = ((arg1 != 0) ? -(arg1) : arg1);
649-
650-
CHECKFLOATVAL(result, isinf(arg1), true);
646+
result = -arg1;
651647
PG_RETURN_FLOAT8(result);
652648
}
653649

@@ -703,16 +699,16 @@ float8smaller(PG_FUNCTION_ARGS)
703699
Datum
704700
float4pl(PG_FUNCTION_ARGS)
705701
{
706-
float8 arg1 = PG_GETARG_FLOAT4(0);
707-
float8 arg2 = PG_GETARG_FLOAT4(1);
702+
float4 arg1 = PG_GETARG_FLOAT4(0);
703+
float4 arg2 = PG_GETARG_FLOAT4(1);
708704
float4 result;
709705

710706
result = arg1 + arg2;
711707

712708
/*
713709
* There isn't any way to check for underflow of addition/subtraction
714-
* because numbers near the underflow value have been already been to the
715-
* point where we can't detect the that the two values were originally
710+
* because numbers near the underflow value have already been rounded to
711+
* the point where we can't detect that the two values were originally
716712
* different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 ==
717713
* 1.4013e-45.
718714
*/
@@ -757,7 +753,6 @@ float4div(PG_FUNCTION_ARGS)
757753
(errcode(ERRCODE_DIVISION_BY_ZERO),
758754
errmsg("division by zero")));
759755

760-
/* Do division in float8, then check for overflow */
761756
result = arg1 / arg2;
762757

763758
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
@@ -2693,7 +2688,7 @@ width_bucket_float8(PG_FUNCTION_ARGS)
26932688
errmsg("operand, lower bound and upper bound cannot be NaN")));
26942689

26952690
/* Note that we allow "operand" to be infinite */
2696-
if (is_infinite(bound1) || is_infinite(bound2))
2691+
if (isinf(bound1) || isinf(bound2))
26972692
ereport(ERROR,
26982693
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
26992694
errmsg("lower and upper bounds must be finite")));

src/test/regress/expected/numerology.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ SELECT f1 AS two, max(f3) AS max_float, min(f3) as min_float
9292
ORDER BY two, max_float, min_float;
9393
two | max_float | min_float
9494
-----+----------------------+-----------------------
95-
1 | 1.2345678901234e+200 | 0
95+
1 | 1.2345678901234e+200 | -0
9696
2 | 0 | -1.2345678901234e+200
9797
(2 rows)
9898

@@ -104,7 +104,7 @@ SELECT f1 AS two, max(f3) AS max_float, min(f3) AS min_float
104104
ORDER BY two, max_float, min_float;
105105
two | max_float | min_float
106106
-----+----------------------+-----------------------
107-
1 | 1.2345678901234e+200 | 0
107+
1 | 1.2345678901234e+200 | -0
108108
2 | 0 | -1.2345678901234e+200
109109
(2 rows)
110110

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
--
2+
-- NUMEROLOGY
3+
-- Test various combinations of numeric types and functions.
4+
--
5+
--
6+
-- Test implicit type conversions
7+
-- This fails for Postgres v6.1 (and earlier?)
8+
-- so let's try explicit conversions for now - tgl 97/05/07
9+
--
10+
CREATE TABLE TEMP_FLOAT (f1 FLOAT8);
11+
INSERT INTO TEMP_FLOAT (f1)
12+
SELECT float8(f1) FROM INT4_TBL;
13+
INSERT INTO TEMP_FLOAT (f1)
14+
SELECT float8(f1) FROM INT2_TBL;
15+
SELECT '' AS ten, f1 FROM TEMP_FLOAT
16+
ORDER BY f1;
17+
ten | f1
18+
-----+-------------
19+
| -2147483647
20+
| -123456
21+
| -32767
22+
| -1234
23+
| 0
24+
| 0
25+
| 1234
26+
| 32767
27+
| 123456
28+
| 2147483647
29+
(10 rows)
30+
31+
-- int4
32+
CREATE TABLE TEMP_INT4 (f1 INT4);
33+
INSERT INTO TEMP_INT4 (f1)
34+
SELECT int4(f1) FROM FLOAT8_TBL
35+
WHERE (f1 > -2147483647) AND (f1 < 2147483647);
36+
INSERT INTO TEMP_INT4 (f1)
37+
SELECT int4(f1) FROM INT2_TBL;
38+
SELECT '' AS nine, f1 FROM TEMP_INT4
39+
ORDER BY f1;
40+
nine | f1
41+
------+--------
42+
| -32767
43+
| -1234
44+
| -1004
45+
| -35
46+
| 0
47+
| 0
48+
| 0
49+
| 1234
50+
| 32767
51+
(9 rows)
52+
53+
-- int2
54+
CREATE TABLE TEMP_INT2 (f1 INT2);
55+
INSERT INTO TEMP_INT2 (f1)
56+
SELECT int2(f1) FROM FLOAT8_TBL
57+
WHERE (f1 >= -32767) AND (f1 <= 32767);
58+
INSERT INTO TEMP_INT2 (f1)
59+
SELECT int2(f1) FROM INT4_TBL
60+
WHERE (f1 >= -32767) AND (f1 <= 32767);
61+
SELECT '' AS five, f1 FROM TEMP_INT2
62+
ORDER BY f1;
63+
five | f1
64+
------+-------
65+
| -1004
66+
| -35
67+
| 0
68+
| 0
69+
| 0
70+
(5 rows)
71+
72+
--
73+
-- Group-by combinations
74+
--
75+
CREATE TABLE TEMP_GROUP (f1 INT4, f2 INT4, f3 FLOAT8);
76+
INSERT INTO TEMP_GROUP
77+
SELECT 1, (- i.f1), (- f.f1)
78+
FROM INT4_TBL i, FLOAT8_TBL f;
79+
INSERT INTO TEMP_GROUP
80+
SELECT 2, i.f1, f.f1
81+
FROM INT4_TBL i, FLOAT8_TBL f;
82+
SELECT DISTINCT f1 AS two FROM TEMP_GROUP ORDER BY 1;
83+
two
84+
-----
85+
1
86+
2
87+
(2 rows)
88+
89+
SELECT f1 AS two, max(f3) AS max_float, min(f3) as min_float
90+
FROM TEMP_GROUP
91+
GROUP BY f1
92+
ORDER BY two, max_float, min_float;
93+
two | max_float | min_float
94+
-----+----------------------+-----------------------
95+
1 | 1.2345678901234e+200 | 0
96+
2 | 0 | -1.2345678901234e+200
97+
(2 rows)
98+
99+
-- GROUP BY a result column name is not legal per SQL92, but we accept it
100+
-- anyway (if the name is not the name of any column exposed by FROM).
101+
SELECT f1 AS two, max(f3) AS max_float, min(f3) AS min_float
102+
FROM TEMP_GROUP
103+
GROUP BY two
104+
ORDER BY two, max_float, min_float;
105+
two | max_float | min_float
106+
-----+----------------------+-----------------------
107+
1 | 1.2345678901234e+200 | 0
108+
2 | 0 | -1.2345678901234e+200
109+
(2 rows)
110+
111+
SELECT f1 AS two, (max(f3) + 1) AS max_plus_1, (min(f3) - 1) AS min_minus_1
112+
FROM TEMP_GROUP
113+
GROUP BY f1
114+
ORDER BY two, min_minus_1;
115+
two | max_plus_1 | min_minus_1
116+
-----+----------------------+-----------------------
117+
1 | 1.2345678901234e+200 | -1
118+
2 | 1 | -1.2345678901234e+200
119+
(2 rows)
120+
121+
SELECT f1 AS two,
122+
max(f2) + min(f2) AS max_plus_min,
123+
min(f3) - 1 AS min_minus_1
124+
FROM TEMP_GROUP
125+
GROUP BY f1
126+
ORDER BY two, min_minus_1;
127+
two | max_plus_min | min_minus_1
128+
-----+--------------+-----------------------
129+
1 | 0 | -1
130+
2 | 0 | -1.2345678901234e+200
131+
(2 rows)
132+
133+
DROP TABLE TEMP_INT2;
134+
DROP TABLE TEMP_INT4;
135+
DROP TABLE TEMP_FLOAT;
136+
DROP TABLE TEMP_GROUP;

0 commit comments

Comments
 (0)