[PATCH] Remove unused scan tuple slots from Sort, IncrementalSort, Material and Memoize

Started by Tatsuya Kawata14 days ago1 messageshackers
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:t253386
psql -h localhost -U postgres

Built from patchset v1 (message #1), August 25, 2026 at 05:02 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 t253386_1 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 t253386_1 && git checkout t253386_1

Patchset v1 (message #1) is on t253386_1

Jump to latest
#1Tatsuya Kawata
kawatatatsuya0913@gmail.com

Hi,

Sort, IncrementalSort, Material and Memoize all call
ExecCreateScanSlotFromOuterPlan() during initialization to allocate a
scan tuple slot, but none of them ever reads that slot. The attached
patch removes those calls. This is a small cleanup; it does not improve
performance or memory usage. The point is to drop initialization work
that nothing uses, together with a comment that no longer matches the
code.

## What is unused

Via ExecInitScanTupleSlot(), ExecCreateScanSlotFromOuterPlan() sets four
more fields besides the slot itself:

scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(...);
scanstate->ps.scandesc = tupledesc;
scanstate->ps.scanopsfixed = tupledesc != NULL;
scanstate->ps.scanops = tts_ops;
scanstate->ps.scanopsset = true;

None of these five is reachable from any reader in the four nodes above.
Where such a node needs to deal with an input tuple it has its own way
of doing so; Sort, for instance, keeps nothing of its own and hands the
child's slot straight to tuplesort.

This is unlike Agg, WindowAgg and Group. Those three do reuse
ss_ScanTupleSlot as a working buffer for an input tuple, which they then
make visible to expression evaluation via the expression context
(firstSlot in nodeAgg.c, for example), so they are left alone here.

The patch also drops this line from MaterialState's header comment in
execnodes.h:

ss.ss_ScanTupleSlot refers to output of underlying plan.

The identical wording in AggState's comment is still accurate, so that
one is kept.

## How it got there

These calls look like a leftover from the days when Sort and Material
really were scan nodes. Back then they wrote the output of the subplan
into a temporary relation with heap_insert() and read it back with
heap_beginscan(), so ss_currentRelation and ss_ScanTupleSlot were used
for their stated purpose. When that approach was dropped, it seems only
the allocation was left behind.

make check-world passes.
Patch attached.

Regards,
Tatsuya Kawata

Attachments:

t253386_1
v1-0001-Remove-unused-scan-tuple-slots-from-Sort-Incremen.patchapplication/octet-stream; name=v1-0001-Remove-unused-scan-tuple-slots-from-Sort-Incremen.patchDownload+0-23