BUG #19586: money division overflow
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
This thread has been committed, so CI has stopped here. Anything below is the last result it produced.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253238psql -h localhost -U postgresBuilt from patchset v2 (message #2), August 04, 2026 at 01:55 AM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t253238_2 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t253238_2 && git checkout t253238_2Patchset v2 (message #2) is on t253238_2
The following bug has been logged on the website:
Bug reference: 19586
Logged by: Michael Malis
Email address: malis@pgrust.com
PostgreSQL version: 18.4
Operating system: Linux x86_64 and Linux aarch64
Description:
cash_div_int64() in src/backend/utils/adt/cash.c guards against division by
zero but not against the INT64_MIN / -1 overflow:
cash_div_int64(Cash c, int64 i)
{
if (unlikely(i == 0))
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), ...));
return c / i;
}
Commit 4f96281587 ("Add overflow checks to money type", 2024-07-19, fixing
bug
#18240) added pg_mul_s64_overflow() checks to cash_mul_int64() and the
float paths, but the division path was not covered.
Steps to reproduce
SELECT '-92233720368547758.08'::money / -1;
Actual results
On x86-64, the hardware division trap is caught by PostgreSQL's SIGFPE
handler and surfaces as a misleading error class for an integer overflow:
ERROR: floating-point exception
DETAIL: An invalid floating-point operation was signaled...
On aarch64, where the division does not trap, the wrong value is returned
silently, with no error:
-$92,233,720,368,547,758.08
i.e. a negative value divided by -1 remains negative.
Expected results
The same treatment int8div() already gives the identical arithmetic, on
every platform:
SELECT (-9223372036854775808)::bigint / -1;
ERROR: bigint out of range
Multiplication in the money type is already guarded and behaves correctly:
SELECT '-92233720368547758.08'::money * -1;
ERROR: money out of range
I would be happy to provide a patch.
Hi, Michael!
Thanks for the report.
Patch attached.
---
Regards,
Rachitskiy Andrey
ср, 29 июл. 2026 г. в 22:54, PG Bug reporting form <noreply@postgresql.org>:
Show quoted text
The following bug has been logged on the website:
Bug reference: 19586
Logged by: Michael Malis
Email address: malis@pgrust.com
PostgreSQL version: 18.4
Operating system: Linux x86_64 and Linux aarch64
Description:cash_div_int64() in src/backend/utils/adt/cash.c guards against division by
zero but not against the INT64_MIN / -1 overflow:cash_div_int64(Cash c, int64 i)
{
if (unlikely(i == 0))
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), ...));
return c / i;
}Commit 4f96281587 ("Add overflow checks to money type", 2024-07-19, fixing
bug
#18240) added pg_mul_s64_overflow() checks to cash_mul_int64() and the
float paths, but the division path was not covered.Steps to reproduce
SELECT '-92233720368547758.08'::money / -1;
Actual results
On x86-64, the hardware division trap is caught by PostgreSQL's SIGFPE
handler and surfaces as a misleading error class for an integer overflow:ERROR: floating-point exception
DETAIL: An invalid floating-point operation was signaled...
On aarch64, where the division does not trap, the wrong value is returned
silently, with no error:-$92,233,720,368,547,758.08
i.e. a negative value divided by -1 remains negative.Expected results
The same treatment int8div() already gives the identical arithmetic, on
every platform:SELECT (-9223372036854775808)::bigint / -1;
ERROR: bigint out of rangeMultiplication in the money type is already guarded and behaves correctly:
SELECT '-92233720368547758.08'::money * -1;
ERROR: money out of rangeI would be happy to provide a patch.
On Wed Jul 29, 2026 at 8:40 PM CDT, Andrey Rachitskiy wrote:
Hi, Michael!
Thanks for the report.
Patch attached.
Hi Andrey,
The patch looks good to me. Thanks for the tests! I think you should
send the patch to pgsql-hackers. Sending the patch on -bugs is not the
right process.
--
Tristan Partin
PostgreSQL Contributors Team
AWS (https://aws.amazon.com)
On Thu, 2026-07-30 at 05:04 +0000, Tristan Partin wrote:
I think you should
send the patch to pgsql-hackers. Sending the patch on -bugs is not the
right process.
A patch to -bugs is perfectly fine.
What might help is a commitfest entry as a reminder. The message ID of
a mail to -bugs will work just fine.
Yours,
Laurenz Albe
On Thu, Jul 30, 2026 at 07:10:32AM +0200, Laurenz Albe wrote:
A patch to -bugs is perfectly fine.
It is. There is no need to duplicate a discussion for a bug on
pgsql-hackers. We handle patches on both lists all the time. Some
may directly post a patch for a bug on pgsql-hackers rather than
beginning a thread on pgsql-bugs, which is also fine. Discussion
duplicates lead to a confusing result.
What might help is a commitfest entry as a reminder. The message ID of
a mail to -bugs will work just fine.
Exactly. That works just fine. We have plenty of these.
--
Michael