40708acd6 added code to have EXPLAIN ANALYZE show the memory or disk
usage for Material nodes. This isn't quite right as if the material
node is rescanned, tuplestore_end() is called and that will result in
the memory usage for that scan being forgotten. What EXPLAIN reports
is the memory used by the final Material rescan. If that's
significantly less than some other rescan, then that's misleading.
The fix is fairly simple, just use tuplestore_clear() instead of
tuplestore_end(). The existing code seems to handle no longer
NULLifying the tuplestore due to the tuplestore_ateof() check.
The misreporting of the storage likely isn't a big deal. I suspect
rescans of Material nodes are not massively common, so maybe it's not
worth backpatching a fix.
Here's an example query showing the issue (modified regression test query)
EXPLAIN ANALYZE
SELECT count(*) FROM (VALUES(10000),(1)) v1(r1)
LEFT JOIN LATERAL (
SELECT * FROM generate_series(1, 2) gs0
LEFT JOIN LATERAL (
SELECT * FROM generate_series(1, v1.r1) gs1
FULL JOIN generate_series(1, v1.r1) gs4 ON false
) ss on true
) q on true;
The outer Material node reports:
master: Storage: Memory Maximum Storage: 17kB
patched: Storage: Memory Maximum Storage: 725kB
Or you can play around swapping the order of the integers in the
VALUES clause to see that master will report the storage used for the
final value. With the patch the order shouldn't affect the result.
Anyone have any opinions on if this is worthy of fixing in the backbranches?
(Function Scan not supporting mark and restore is another matter of
interest with the resulting plan. I'll look at that separately)
David