Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition

Ayush Tiwari <ayushtiwari.slg01@gmail.com>

From: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
To: Fujii Masao <masao.fujii@gmail.com>
Cc: n.kalinin@postgrespro.ru, pgsql-bugs@lists.postgresql.org
Date: 2026-06-05T03:42:20Z
Lists: pgsql-bugs
Hi,

On Fri, 5 Jun 2026 at 08:49, Fujii Masao <masao.fujii@gmail.com> wrote:

>
> Commit 257c8231bf9 changed pg_buffercache_pages() to materialize rows
> directly
> into a tuplestore. As a result, the function started using the
> caller-supplied
> RECORD descriptor as rsinfo->setDesc, so a mismatched column definition
> list
> could cause tuplestore_putvalues() to interpret returned Datums with
> incorrect
> types.
>
> Before that change, pg_buffercache_pages() exposed its actual tuple
> descriptor
> to the executor, allowing the executor's existing rowtype checks to reject
> incompatible definitions with a normal error.
>
> The attached patch restores that behavior while keeping the
> materialized-SRF
> implementation. Thoughts?
>

Thanks for the patch, Fujii-san!

I was looking into the bug last night, and the approach looks right to me.

This still means InitMaterializedSRF() briefly creates the caller-derived
descriptor before rsinfo->setDesc is replaced. That seems acceptable here:
the descriptor lives only in the per-query context, and avoiding a local
copy of InitMaterializedSRF() keeps the fix much smaller and less fragile.

One small nit: build_buffercache_pages_tupledesc() names attribute 8
"usage_count", while the existing pg_buffercache view and the test use
"usagecount". This probably does not affect the tupledesc_match() check,
but I think it would be better to keep the existing spelling for
consistency.

Regards,
Ayush

Commits

  1. pg_buffercache: restore rowtype verification in pg_buffercache_pages()

  2. Modernize and optimize pg_buffercache_pages()