提交 f9ac414c 编写于 作者: B Bruce Momjian

Fix float4/8 to handle Infinity and Nan consistently, e.g. Infinity is a

valid result from a computation if one of the input values was infinity.
The previous code assumed an operation that returned infinity was an
overflow.

Handle underflow/overflow consistently, and add checks for aggregate
overflow.

Consistently prevent Inf/Nan from being cast to integer data types.

Fix INT_MIN % -1 to prevent overflow.

Update regression results for new error text.

Per report from Roman Kononov.
上级 0b56be83
此差异已折叠。
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.75 2006/10/04 00:29:59 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.76 2007/01/02 20:00:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1124,6 +1124,11 @@ int4mod(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
/* SELECT ((-2147483648)::int4) % (-1); causes a floating point exception */
if (arg1 == INT_MIN && arg2 == -1)
PG_RETURN_INT32(0);
/* No overflow is possible */
PG_RETURN_INT32(arg1 % arg2);
......
......@@ -8,14 +8,14 @@ INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 ');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
ERROR: type "real" value out of range: overflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
ERROR: type "real" value out of range: overflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
ERROR: type "real" value out of range: underflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
ERROR: type "real" value out of range: underflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
ERROR: value out of range: overflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
ERROR: value out of range: overflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
ERROR: value out of range: underflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
ERROR: value out of range: underflow
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type real: ""
......@@ -72,7 +72,11 @@ ERROR: invalid input syntax for type real: "NaN x"
SELECT ' INFINITY x'::float4;
ERROR: invalid input syntax for type real: " INFINITY x"
SELECT 'Infinity'::float4 + 100.0;
ERROR: type "double precision" value out of range: overflow
?column?
----------
Infinity
(1 row)
SELECT 'Infinity'::float4 / 'Infinity'::float4;
?column?
----------
......
......@@ -8,14 +8,14 @@ INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 ');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
ERROR: type "real" value out of range: overflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
ERROR: type "real" value out of range: overflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
ERROR: type "real" value out of range: underflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
ERROR: type "real" value out of range: underflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
ERROR: value out of range: overflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
ERROR: value out of range: overflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
ERROR: value out of range: underflow
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
ERROR: value out of range: underflow
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type real: ""
......@@ -72,7 +72,11 @@ ERROR: invalid input syntax for type real: "NaN x"
SELECT ' INFINITY x'::float4;
ERROR: invalid input syntax for type real: " INFINITY x"
SELECT 'Infinity'::float4 + 100.0;
ERROR: type "double precision" value out of range: overflow
?column?
----------
Infinity
(1 row)
SELECT 'Infinity'::float4 / 'Infinity'::float4;
?column?
----------
......
......@@ -72,7 +72,11 @@ ERROR: invalid input syntax for type double precision: "NaN x"
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
SELECT 'Infinity'::float8 + 100.0;
ERROR: type "double precision" value out of range: overflow
?column?
----------
Infinity
(1 row)
SELECT 'Infinity'::float8 / 'Infinity'::float8;
?column?
----------
......@@ -342,15 +346,15 @@ UPDATE FLOAT8_TBL
SET f1 = FLOAT8_TBL.f1 * '-1'
WHERE FLOAT8_TBL.f1 > '0.0';
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
ERROR: type "double precision" value out of range: overflow
ERROR: value out of range: overflow
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
ERROR: result is out of range
ERROR: value out of range: overflow
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
ERROR: cannot take logarithm of zero
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
ERROR: cannot take logarithm of a negative number
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
ERROR: result is out of range
ERROR: value out of range: underflow
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
ERROR: division by zero
SELECT '' AS five, * FROM FLOAT8_TBL;
......
......@@ -80,7 +80,11 @@ ERROR: invalid input syntax for type double precision: "NaN x"
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
SELECT 'Infinity'::float8 + 100.0;
ERROR: type "double precision" value out of range: overflow
?column?
----------
Infinity
(1 row)
SELECT 'Infinity'::float8 / 'Infinity'::float8;
?column?
----------
......@@ -350,15 +354,15 @@ UPDATE FLOAT8_TBL
SET f1 = FLOAT8_TBL.f1 * '-1'
WHERE FLOAT8_TBL.f1 > '0.0';
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
ERROR: type "double precision" value out of range: overflow
ERROR: value out of range: overflow
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
ERROR: result is out of range
ERROR: value out of range: overflow
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
ERROR: cannot take logarithm of zero
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
ERROR: cannot take logarithm of a negative number
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
ERROR: result is out of range
ERROR: value out of range: underflow
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
ERROR: division by zero
SELECT '' AS five, * FROM FLOAT8_TBL;
......
......@@ -80,7 +80,11 @@ ERROR: invalid input syntax for type double precision: "NaN x"
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
SELECT 'Infinity'::float8 + 100.0;
ERROR: type "double precision" value out of range: overflow
?column?
----------
Infinity
(1 row)
SELECT 'Infinity'::float8 / 'Infinity'::float8;
?column?
----------
......@@ -350,15 +354,15 @@ UPDATE FLOAT8_TBL
SET f1 = FLOAT8_TBL.f1 * '-1'
WHERE FLOAT8_TBL.f1 > '0.0';
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
ERROR: type "double precision" value out of range: overflow
ERROR: value out of range: overflow
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
ERROR: result is out of range
ERROR: value out of range: overflow
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
ERROR: cannot take logarithm of zero
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
ERROR: cannot take logarithm of a negative number
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
ERROR: result is out of range
ERROR: value out of range: underflow
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
ERROR: division by zero
SELECT '' AS five, * FROM FLOAT8_TBL;
......
......@@ -72,7 +72,11 @@ ERROR: invalid input syntax for type double precision: "NaN x"
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
SELECT 'Infinity'::float8 + 100.0;
ERROR: type "double precision" value out of range: overflow
?column?
----------
Infinity
(1 row)
SELECT 'Infinity'::float8 / 'Infinity'::float8;
?column?
----------
......@@ -342,15 +346,15 @@ UPDATE FLOAT8_TBL
SET f1 = FLOAT8_TBL.f1 * '-1'
WHERE FLOAT8_TBL.f1 > '0.0';
SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
ERROR: type "double precision" value out of range: overflow
ERROR: value out of range: overflow
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
ERROR: result is out of range
ERROR: value out of range: overflow
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
ERROR: cannot take logarithm of zero
SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
ERROR: cannot take logarithm of a negative number
SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f;
ERROR: result is out of range
ERROR: value out of range: underflow
SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
ERROR: division by zero
SELECT '' AS five, * FROM FLOAT8_TBL;
......
......@@ -11,10 +11,10 @@ INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
-- test for over and under flow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册