Re: BUG #19810: to_char(): float V-format overflow yields 'Infinity' or NaN; format after decimal point dropped

From: Andrey Rachitskiy <pl0h0yp1(at)gmail(dot)com>
To: 303677365(at)qq(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19810: to_char(): float V-format overflow yields 'Infinity' or NaN; format after decimal point dropped
Date: 2026-10-30 21:09:41
Message-ID: CAB8bMiu+KeLVhNx0TWnj5O41FLgBZFb+fP5gmkJDV7gj-ZqTKw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

пт, 30 окт. 2026 г. в 12:13, PG Bug reporting form <noreply(at)postgresql(dot)org>:

> Issue 1: float4/float8 V (decimal shift) format has no overflow check.
>
> The V template multiplies the value by 10^n, where n is the number of
> digits
> after V. For the float types the scale factor is computed as a double; when
> 10^n itself overflows, the multiplication silently produces Infinity or
> NaN,
> and to_char() returns that as literal text.
>
> - A perfectly representable result is destroyed:
> to_char(1e-300::float8, 'FM9V' || repeat('9', 309)) -> "Infinity"
> The true result is 1e-300 * 10^309 = 1e9; the same format with numeric
> returns 1000000000.
> - Zero becomes NaN:
> to_char(0::float8, 'FM9V' || repeat('9', 309)) -> "NaN" (0 * inf)
> float4 already does this at n = 39.
> - Ordinary overflow returns literal text instead of "#" or an error:
> to_char(1e308::float8, 'FM9V9999999') -> "Infinity"
> while the equivalent SQL arithmetic 1e308::float8 * 1e7 raises
> ERROR: value out of range: overflow
> and the sibling int8 path raises "bigint out of range".
> One fewer 9, to_char(1e308::float8, 'FM9V999999'), returns "#######" -
> the documented overflow marker - so two adjacent format widths disagree on
> how overflow is represented.
> - An already-infinite input is also inconsistent within the same function:
> to_char('Infinity'::float8, 'FM9999') -> "####"
> to_char('Infinity'::float8, 'FM9999999999') -> "Infinity"
>
> The sibling branches are guarded (int4/int8 raise errors, numeric is
> exact);
> only the float4/float8 paths lack the check.
>
>
In the attached patch, scaling is done in numeric instead, using
numeric_power() and numeric_mul().
If the number doesn't fit, the error is reported properly - float8 via
float_overflow_error(), float4 via numeric_float4().

> Issue 2: template patterns after the decimal point are silently dropped,
> losing the sign.
>
>
Tom fixed it on 20/10/26 in master (776df8a6d7c) and in REL_19_STABLE
(61bb2214892) - BUG 19771

--
Regards,
Rachitskiy Andrey

Attachment Content-Type Size
0001-Fix-float-to_char-V-scaling.patch text/x-patch 5.4 KB

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Andrey Rachitskiy 2026-10-30 21:36:38 Re: BUG #19815: 004_sni.pl fails deterministically with OpenSSL 1.1.1 (tests 75 and 86)
Previous Message Tom Lane 2026-10-30 21:04:33 Re: BUG #19411: libpq 16.x exhibits a memory leak when connections are repeatedly created and destroyed