Thread: pgsql: Improve the numeric width_bucket() computation.

pgsql: Improve the numeric width_bucket() computation.

From
Dean Rasheed
Date:
Improve the numeric width_bucket() computation.

Formerly, the computation of the bucket index involved calling
div_var() with a scale determined by select_div_scale(), and then
taking the floor of the result. That involved computing anything from
16 to 1000 digits after the decimal point, only for floor_var() to
throw them away. In addition, the quotient was computed with rounding
in the final digit, which meant that in rare cases the whole result
could round up to the wrong bucket, and could exceed count. Thus it
was also necessary to clamp the result to the range [1, count], though
that didn't prevent the result being in the wrong internal bucket.

Instead, compute the quotient using floor division, which guarantees
the correct result, as specified by the SQL spec, and doesn't need to
be clamped. This is both much simpler and more efficient, since it no
longer computes any quotient digits after the decimal point.

In addition, it is not necessary to have separate code to handle
reversed bounds, since the signs cancel out when dividing.

As with b0e9e4d76c and a2a0c7c29e, no back-patch.

Dean Rasheed, reviewed by Joel Jacobson.

Discussion: https://postgr.es/m/CAEZATCVbJH%2BLE9EXW8Rk3AxLe%3DjbOk2yrT_AUJGGh5Rah6zoeg%40mail.gmail.com

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/0dcf753bd82a786922f4149248117b113353e257

Modified Files
--------------
src/backend/utils/adt/numeric.c | 49 +++++++++++++++--------------------------
1 file changed, 18 insertions(+), 31 deletions(-)