I have taken a look at this discussion, at the code and I am confused how we 
choose tuple table slot (TTS) type in PG. May be you can clarify this topic or 
me. 

1. Brief intro. There are four types of TTS. Plan tree «leaves»:
- buffer heap (produced by index and table scans, has system columns and keeps 
shared buffer pins)
- heap (produced by FDW: has system columns, but doesn’t keep any pins)
- minimal (produced by values and materializations nodes like sort, agg, etc.)
Plan «branches»:
- virtual (keeps datum references to the columns of the tuples in the child 
nodes)

Virtual TTS is cheeper to copy among the plan (as we copy datum references), 
but more expensive to materialize (we have to construct a tuple from pieces).

Leaves are cheeper to materialize (as we make a memcmp under hood), but very 
expensive to copy (we copy the value, not the datum reference).

2. If we take a look at the materialize nodes in the plan, they produce 
different result TTS.
- Outer child TTS type: gater, gather merge, lock rows, limit;
- Minimal: material, sort, incremental sort, memoize, unique, hash, setup (can 
be heap as well);
- Virtual: group, agg, window agg.

From my point of view, the materialization node should preserve the incoming 
TTS type. For the sort node (that materializes incoming tuples as minimal) it 
is ok to output minimal result as well. Looks that unique should use the outer 
child’d TTS (instead of hardcoded minimal). But can anyone explain me why do 
group, agg and window agg return the virtual instead of the same TTS type as 
outer child has? Do we expect that the parent node exists and requires exactly 
virtual tuples (but what if the parent node is sort and benefits from minimal 
TTS)? So, it looks like we need to take a look not only at the unique, but also 
inspect all the materialization nodes.




Reply via email to