Prevent numeric overflows in parallel numeric aggregates.
authorDean Rasheed <dean.a.rasheed@gmail.com>
Mon, 5 Jul 2021 09:16:42 +0000 (10:16 +0100)
committerDean Rasheed <dean.a.rasheed@gmail.com>
Mon, 5 Jul 2021 09:16:42 +0000 (10:16 +0100)
commitf025f2390e13d7da69da595086fb982bbaf7f329
tree7e5127e4a89bd14e9b7157a50dc3ef9f092cb865
parent903d9aa7801e3198ca24e90be805362ad11b6ec3
Prevent numeric overflows in parallel numeric aggregates.

Formerly various numeric aggregate functions supported parallel
aggregation by having each worker convert partial aggregate values to
Numeric and use numeric_send() as part of serializing their state.
That's problematic, since the range of Numeric is smaller than that of
NumericVar, so it's possible for it to overflow (on either side of the
decimal point) in cases that would succeed in non-parallel mode.

Fix by serializing NumericVars instead, to avoid the overflow risk and
ensure that parallel and non-parallel modes work the same.

A side benefit is that this improves the efficiency of the
serialization/deserialization code, which can make a noticeable
difference to performance with large numbers of parallel workers.

No back-patch due to risk from changing the binary format of the
aggregate serialization states, as well as lack of prior field
complaints and low probability of such overflows in practice.

Patch by me. Thanks to David Rowley for review and performance
testing, and Ranier Vilela for an additional suggestion.

Discussion: https://postgr.es/m/CAEZATCUmeFWCrq2dNzZpRj5+6LfN85jYiDoqm+ucSXhb9U2TbA@mail.gmail.com
src/backend/utils/adt/numeric.c
src/test/regress/expected/numeric.out
src/test/regress/sql/numeric.sql