| From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Cc: | imchifan8(at)gmail(dot)com |
| Subject: | BUG #19898: int4_avg_accum_inv wraps below INT64_MIN instead of raising an error |
| Date: | 2026-11-12 23:42:08 |
| Message-ID: | 19898-5617a53e503f6184@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 19898
Logged by: Noah
Email address: imchifan8(at)gmail(dot)com
PostgreSQL version: 18.6
Operating system: Linux/amd64
Description:
pg_catalog.int4_avg_accum_inv silently wraps an inverse-transition sum below
INT64_MIN. Given a reachable state with count 4294967298 and sum INT64_MIN,
removing the input value 1 returns a sum of INT64_MAX instead of reporting
numeric-value-out-of-range.
The state is mathematically reachable by adding 1, then 2^32 copies of
INT32_MIN, then -1. Removing the leading 1 makes the exact next sum
INT64_MIN - 1, which cannot be represented by bigint and should raise an
out-of-range error.
How to repeat:
\set ON_ERROR_STOP on
-- This state is mathematically reachable: +1, followed by 2^32 copies of
-- INT32_MIN, followed by -1, yields count 4294967298 and sum INT64_MIN.
-- Removing the leading +1 makes the exact sum INT64_MIN - 1.
SELECT pg_catalog.int4_avg_accum_inv(
ARRAY[4294967298::bigint, '-9223372036854775808'::bigint],
1::integer) AS inverse_state;
The output was:
inverse_state
----------------------------------
{4294967297,9223372036854775807}
(1 row)
The returned count is reduced by one as expected, but the sum wraps from the
unrepresentable INT64_MIN - 1 result to INT64_MAX.
The issue was reproduced on PostgreSQL 18.6 on Linux/amd64. This occurs when
an int4 moving aggregate removes a value from a reachable state whose exact
next sum is below INT64_MIN.
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Daniel Gustafsson | 2026-11-13 00:00:07 | Re: BUG #19702: decode() accepts Base64 payload after terminal padding |
| Previous Message | Manu | 2026-11-12 23:00:40 | Re: BUG #19602: Vuln46: citext split_part silently returns NULL for a zero field position instead of raising core sp |