Re: [PATCH] doc: outline all planner nodes

Started by Brian Brennglass3 months ago5 messagesdocs
Beta feature

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.

appliessuccessCI history

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:t253147
psql -h localhost -U postgres

Built from patchset v5 (message #5), October 23, 2026 at 09:40 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 t253147_5 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253147_5 && git checkout t253147_5

Patchset v5 (message #5) is on t253147_5

Jump to latest
#1Brian Brennglass
brian@supabase.io

Just rebasing the previous patch. Also generated a preview site:
- https://lovely-salmiakki-fdb4a0.netlify.app/

Attachments:

t253147_1
v3-0001-doc-outline-all-planner-nodes.patchapplication/octet-stream; name=v3-0001-doc-outline-all-planner-nodes.patchDownload+2260-9
#2Marcos Pegoraro
marcos@f10.com.br
In reply to: Brian Brennglass (#1)

Em ter., 21 de jul. de 2026 às 15:34, Brian Brennglass <brian@supabase.io>
escreveu:

Just rebasing the previous patch. Also generated a preview site:

cool this patch, I think it's a valuable contribution.

- I don't know what version you are running, but rows is now a numeric, not
integer anymore.
So rows should have decimals, like rows=199999.00 loops=1)
- Maybe you add previous commands to create that table and later run that
select, so the user can replicate how to have that occurrence.
Like you do on "Named Tuplestore Scan"
- Maybe you could run with EXPLAIN (costs off), because the goal is to show
the plan, not the cost.

regards
Marcos

#3Brian Brennglass
brian@supabase.io
In reply to: Brian Brennglass (#1)
Fwd: [PATCH] doc: outline all planner nodes

---------- Forwarded message ---------
From: Brian Brennglass <brian@supabase.io>
Date: Thu, 30 Jul 2026 at 15:34
Subject: Re: [PATCH] doc: outline all planner nodes
To: Marcos Pegoraro <marcos@f10.com.br>

cool this patch, I think it's a valuable contribution.

Thank you :)

I don't know what version you are running, but rows is now a numeric, not

integer anymore.

So rows should have decimals, like rows=199999.00 loops=1)

I was running PG 17. I just tested it for PG18, and it produced floats, but
only for the "actual cost" in EXPLAIN ANALYZE. I'll update the examples
that reference ANALYZE.

Just as an aside, I am kind of curious why PG uses decimals to track rows.
Is it now possible to return half a row?

Maybe you add previous commands to create that table and later run that

select, so the user can replicate how to have that occurrence.

Like you do on "Named Tuplestore Scan"

When I first started writing the patch, I had included table definitions,
but I found 2 issues with it:

1. It was noisy

All the extra SQL made the page very long, and I found it hard to follow. I
made an exception for "Named Tuplestore Scan" because the scan is so
obscure that I thought providing a larger example was the only way to make
it understandable.

I put it at the end of its section so the large block wouldn't disrupt the
flow as much. If you think the extra SQL is worth it, I'd be okay
revisiting. At that point, though, it may make sense to break up the doc
into multiple sub-chapters: Scans, Joins, DML... Otherwise, I think readers
would be intimidated by its length.

2. It wouldn't be reliable

The same query can produce different plans depending on server configs,
version, distribution of data within columns, ...

Unless we specify the PG version and configs used for the examples, not all
nodes are going to be consistently reproducible.

I'm not completely opposed to adding setup SQL, but it would also mean
revalidating them between PG releases.

At the moment, I'm thinking the maintenance overhead wouldn't be worth
it, especially
since I expect many readers will use the page to interpret plans they're
already seeing rather than to learn how to reproduce every plan node from
scratch.

- Maybe you could run with EXPLAIN (costs off), because the goal is to

show the plan, not the cost.

I did this for the materialize example[1] because it was just too congested
to read otherwise, but was hesitant to apply it to the other nodes, too. I
thought writing out EXPLAIN (COSTS FALSE) would look a bit strange, as, in
my experience, it's not commonly referenced. I do agree that the costs
aren't useful for the page. I think it's best that I overlook my initial
hesitation. I'll update EXPLAIN to EXPLAIN (COSTS FALSE)

Best,
Brian B.

1. https://lovely-salmiakki-fdb4a0.netlify.app/#MATERIALIZE-OVERVIEW

On Mon, 27 Jul 2026 at 18:54, Marcos Pegoraro <marcos@f10.com.br> wrote:

Show quoted text

Em ter., 21 de jul. de 2026 às 15:34, Brian Brennglass <brian@supabase.io>
escreveu:

Just rebasing the previous patch. Also generated a preview site:

cool this patch, I think it's a valuable contribution.

- I don't know what version you are running, but rows is now a numeric,
not integer anymore.
So rows should have decimals, like rows=199999.00 loops=1)
- Maybe you add previous commands to create that table and later run that
select, so the user can replicate how to have that occurrence.
Like you do on "Named Tuplestore Scan"
- Maybe you could run with EXPLAIN (costs off), because the goal is to
show the plan, not the cost.

regards
Marcos

#4David Rowley
dgrowleyml@gmail.com
In reply to: Brian Brennglass (#3)

On Sat, 1 Aug 2026 at 01:20, Brian Brennglass <brian@supabase.io> wrote:

Just as an aside, I am kind of curious why PG uses decimals to track rows. Is it now possible to return half a row?

It isn't. What the actual rows mean is the total rows returned divided
by the "loops" count. If loop 1 returns 2 rows and loop 2 gives you 3,
then that's 2.50 rows on average. Prior to that change, we'd have only
displayed "rows=2". For smaller average row counts, rounding down is
quite misleading, especially so when the average was below "1.0",
since we would have displayed "rows=0". The extra precision was added
to make that problem 100 times less bad.

More details and links to mailing list discussion in [1]https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=ddb17e387.

David

[1]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=ddb17e387

#5Brian Brennglass
brian@supabase.io
In reply to: David Rowley (#4)

Thanks for the explanation around row tracking.

I re-ran the samples that used EXPLAIN (ANALYZE, ...) and updated all
examples to use (COSTS FALSE). I'm hoping it makes them less noisy.

Beyond that, I expanded a bit on how Hash and Hash Join nodes work in
Postgres.

Pre-rendered the new patch in Netlify to make it easier to peruse:
- https://tubular-palmier-9a2fb3.netlify.app/planner-nodes

Best,
Brian B.

On Fri, 31 Jul 2026 at 23:04, David Rowley <dgrowleyml@gmail.com> wrote:

Show quoted text

On Sat, 1 Aug 2026 at 01:20, Brian Brennglass <brian@supabase.io> wrote:

Just as an aside, I am kind of curious why PG uses decimals to track

rows. Is it now possible to return half a row?

It isn't. What the actual rows mean is the total rows returned divided
by the "loops" count. If loop 1 returns 2 rows and loop 2 gives you 3,
then that's 2.50 rows on average. Prior to that change, we'd have only
displayed "rows=2". For smaller average row counts, rounding down is
quite misleading, especially so when the average was below "1.0",
since we would have displayed "rows=0". The extra precision was added
to make that problem 100 times less bad.

More details and links to mailing list discussion in [1].

David

[1]
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=ddb17e387

Attachments:

t253147_5
v4-0001-doc-outline-all-planner-nodes.patchapplication/octet-stream; name=v4-0001-doc-outline-all-planner-nodes.patchDownload+2334-10