Skip to content

Commit 8ce423b

Browse files
committed
Fix numeric width_bucket() to allow its first argument to be infinite.
While the calculation is not well-defined if the bounds arguments are infinite, there is a perfectly sane outcome if the test operand is infinite: it's just like any other value that's before the first bucket or after the last one. width_bucket_float8() got this right, but I was too hasty about the case when adding infinities to numerics (commit a57d312), so that width_bucket_numeric() just rejected it. Fix that, and sync the relevant error message strings. No back-patch needed, since infinities-in-numeric haven't shipped yet. Discussion: https://postgr.es/m/2465409.1602170063@sss.pgh.pa.us
1 parent b90b79e commit 8ce423b

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

src/backend/utils/adt/numeric.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,10 +1724,11 @@ width_bucket_numeric(PG_FUNCTION_ARGS)
17241724
ereport(ERROR,
17251725
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
17261726
errmsg("operand, lower bound, and upper bound cannot be NaN")));
1727-
else
1727+
/* We allow "operand" to be infinite; cmp_numerics will cope */
1728+
if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
17281729
ereport(ERROR,
17291730
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1730-
errmsg("operand, lower bound, and upper bound cannot be infinity")));
1731+
errmsg("lower and upper bounds must be finite")));
17311732
}
17321733

17331734
init_var(&result_var);

src/test/regress/expected/numeric.out

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,10 +1316,8 @@ SELECT width_bucket('NaN', 3.0, 4.0, 888);
13161316
ERROR: operand, lower bound, and upper bound cannot be NaN
13171317
SELECT width_bucket(0::float8, 'NaN', 4.0::float8, 888);
13181318
ERROR: operand, lower bound, and upper bound cannot be NaN
1319-
SELECT width_bucket('inf', 3.0, 4.0, 888);
1320-
ERROR: operand, lower bound, and upper bound cannot be infinity
13211319
SELECT width_bucket(2.0, 3.0, '-inf', 888);
1322-
ERROR: operand, lower bound, and upper bound cannot be infinity
1320+
ERROR: lower and upper bounds must be finite
13231321
SELECT width_bucket(0::float8, '-inf', 4.0::float8, 888);
13241322
ERROR: lower and upper bounds must be finite
13251323
-- normal operation
@@ -1362,8 +1360,19 @@ SELECT
13621360
10.0000000000001 | 6 | 6 | 0 | 0 | 5 | 5 | 21 | 21 | 8 | 8
13631361
(19 rows)
13641362

1365-
-- for float8 only, check positive and negative infinity: we require
1363+
-- Check positive and negative infinity: we require
13661364
-- finite bucket bounds, but allow an infinite operand
1365+
SELECT width_bucket(0.0::numeric, 'Infinity'::numeric, 5, 10); -- error
1366+
ERROR: lower and upper bounds must be finite
1367+
SELECT width_bucket(0.0::numeric, 5, '-Infinity'::numeric, 20); -- error
1368+
ERROR: lower and upper bounds must be finite
1369+
SELECT width_bucket('Infinity'::numeric, 1, 10, 10),
1370+
width_bucket('-Infinity'::numeric, 1, 10, 10);
1371+
width_bucket | width_bucket
1372+
--------------+--------------
1373+
11 | 0
1374+
(1 row)
1375+
13671376
SELECT width_bucket(0.0::float8, 'Infinity'::float8, 5, 10); -- error
13681377
ERROR: lower and upper bounds must be finite
13691378
SELECT width_bucket(0.0::float8, 5, '-Infinity'::float8, 20); -- error

src/test/regress/sql/numeric.sql

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,6 @@ SELECT width_bucket(5.0::float8, 3.0::float8, 4.0::float8, -5);
831831
SELECT width_bucket(3.5::float8, 3.0::float8, 3.0::float8, 888);
832832
SELECT width_bucket('NaN', 3.0, 4.0, 888);
833833
SELECT width_bucket(0::float8, 'NaN', 4.0::float8, 888);
834-
SELECT width_bucket('inf', 3.0, 4.0, 888);
835834
SELECT width_bucket(2.0, 3.0, '-inf', 888);
836835
SELECT width_bucket(0::float8, '-inf', 4.0::float8, 888);
837836

@@ -876,8 +875,12 @@ SELECT
876875
width_bucket(operand_f8, -25, 25, 10) AS wb_5f
877876
FROM width_bucket_test;
878877

879-
-- for float8 only, check positive and negative infinity: we require
878+
-- Check positive and negative infinity: we require
880879
-- finite bucket bounds, but allow an infinite operand
880+
SELECT width_bucket(0.0::numeric, 'Infinity'::numeric, 5, 10); -- error
881+
SELECT width_bucket(0.0::numeric, 5, '-Infinity'::numeric, 20); -- error
882+
SELECT width_bucket('Infinity'::numeric, 1, 10, 10),
883+
width_bucket('-Infinity'::numeric, 1, 10, 10);
881884
SELECT width_bucket(0.0::float8, 'Infinity'::float8, 5, 10); -- error
882885
SELECT width_bucket(0.0::float8, 5, '-Infinity'::float8, 20); -- error
883886
SELECT width_bucket('Infinity'::float8, 1, 10, 10),

0 commit comments

Comments
 (0)