Re: BUG #19639: EXPLAIN (FORMAT JSON) emits a 309-digit cost value, and the node still reports "Disabled": false

From: Manuel Reyes Bravo <manuelreyesbravo(at)gmail(dot)com>
To: David Rowley <dgrowleyml(at)gmail(dot)com>
Cc: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19639: EXPLAIN (FORMAT JSON) emits a 309-digit cost value, and the node still reports "Disabled": false
Date: 2026-08-24 17:01:57
Message-ID: CA+bCEdBOM2QaVOaGpa-A-Ucctzzxy+pmU7x=vmOb7cG3BE1bxA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

> Does serde_json parse it if you add a .0 to the end of the number?

It already has one -- EXPLAIN prints costs with %.2f, so the literal ends
in ".00" as emitted. serde_json 1.0 rejects it either way, and also
rejects the bare literal parsed as f64. But you are right that this is
its problem rather than PostgreSQL's, and I should correct my own report:
I claimed most plan-analysis tooling would choke on it and had not
measured that. Measured now:

Python 3 json (stdlib) parses fine -> 1.7976931348623157e+308
jq 1.7 parses fine
serde_json 1.0 fails -> number out of range

One parser, not most tooling. I will raise it with serde_json.

That leaves the second half of my report, and having gone looking, I am
withdrawing that too. I built a minimal test AM (the one from #19638)
whose amcostestimate simply returns DBL_MAX, and on 18.6:

"Node Type": "Index Scan"
"Total Cost": 179769313486231570814527423731704356798...
"Disabled": false

So core is faithfully propagating a cost the AM handed it, and
"Disabled": false is correct -- the node is not disabled, it is merely
absurdly expensive. I had read that flag as meaning something it does not
mean, and built an argument about self-contradictory output on top of it.
There is no inconsistency here, and nothing specific to 19: 18 does the
same thing when an AM reports that cost.

The origin is pgvectorscale's amcostestimate. I will take it there, where
it belongs.

Sorry for the noise. Both of these came from comparing 18 and 19 output
and reading a difference as a defect without first checking what produced
it, which is the same mistake I made in #19638.

El lun, 24 ago 2026 a las 9:52, David Rowley (<dgrowleyml(at)gmail(dot)com>)
escribió:

> On Tue, 25 Aug 2026 at 00:16, PG Bug reporting form
> <noreply(at)postgresql(dot)org> wrote:
> > On 19beta3, EXPLAIN (FORMAT JSON) can emit a cost of DBL_MAX, rendered
> as a
> > 309-digit number. serde_json rejects it with "number out of range", and I
> > would
> > expect most plan-analysis tooling to have the same problem, since there
> is
> > no
> > way for a client to consume it other than parsing the number as text.
>
> Does serde_json parse it if you add a .0 to the end of the number?
>
> Maybe they should consider switching to doubles if the number
> overflows the integer type they're using.
>
> RFC8259 does say:
>
> "This specification allows implementations to set limits on the range
> and precision of numbers accepted. Since software that implements
> IEEE 754 binary64 (double precision) numbers [IEEE754] is generally
> available and widely used, good interoperability can be achieved by
> implementations that expect no more precision or range than these
> provide, in the sense that implementations will approximate JSON
> numbers within the expected precision. A JSON number such as 1E400
> or 3.141592653589793238462643383279 may indicate potential
> interoperability problems, since it suggests that the software that
> created it expects receiving software to have greater capabilities
> for numeric magnitude and precision than is widely available."
>
> So it does seem a bit poor if their parser failed on DBL_MAX.
>
> David
>

--
Saludos cordiales,

Manuel Reyes

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Andrey Rachitskiy 2026-08-24 18:19:54 Re: BUG #19638: Planner chooses an index-only scan for an index AM without amcanreturn, and execution fails
Previous Message Manuel Reyes Bravo 2026-08-24 16:51:43 Re: BUG #19638: Planner chooses an index-only scan for an index AM without amcanreturn, and execution fails