[PATCH] Fix improper tuple deallocation in import_pg_statist()

From: yonghao_lee <yonghao_lee(at)qq(dot)com>
To: pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: [PATCH] Fix improper tuple deallocation in import_pg_statist()
Date: 2026-03-05 00:40:10
Message-ID: tencent_CA1315EE8FB9C62F742C71E95FAD72214205@qq.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi hackers,

I found a tuple deallocation issue in the import_pg_statistic() function
in src/backend/statistics/extended_stats_funcs.c. The code uses pfree() to release a
HeapTuple, which doesn't properly free the underlying tuple data.

Bug Description:
================

In import_pg_statistic(), after heap_form_tuple() creates a HeapTuple and
heap_copy_tuple_as_datum() copies it to a Datum, the code attempts to free
the temporary HeapTuple using pfree():

&nbsp; &nbsp; pgstup = heap_form_tuple(RelationGetDescr(pgsd), values, nulls);
&nbsp; &nbsp; pgstdat = heap_copy_tuple_as_datum(pgstup, RelationGetDescr(pgsd));
&nbsp; &nbsp; pfree(pgstup);&nbsp; /* <-- BUG: Improper tuple release */

The Problem:
============

HeapTuple is a pointer to HeapTupleData structure, which contains a nested
pointer t_data pointing to the actual tuple header and data:

&nbsp; &nbsp; typedef struct HeapTupleData {
&nbsp; &nbsp; &nbsp; &nbsp; uint32&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t_len;
&nbsp; &nbsp; &nbsp; &nbsp; ItemPointerData t_self;
&nbsp; &nbsp; &nbsp; &nbsp; Oid&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;t_tableOid;
&nbsp; &nbsp; &nbsp; &nbsp; HeapTupleHeader t_data;
&nbsp; &nbsp; } HeapTupleData;

Using pfree(pgstup) only frees the HeapTupleData structure itself
, but leaves the underlying tuple data unfreed.

The Fix:
========

Replace pfree(pgstup) with heap_freetuple(pgstup), which properly frees both
the HeapTupleData structure and the underlying t_data:

&nbsp; &nbsp; -&nbsp; &nbsp; pfree(pgstup);
&nbsp; &nbsp; +&nbsp; &nbsp; heap_freetuple(pgstup);

Patch:
======
---
&nbsp;src/backend/statistics/extended_stats_funcs.c | 2 +-
&nbsp;1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backend/statistics/extended_stats_funcs.c b/src/backend/statistics/extended_stats_funcs.c
index 0ec77a6..9279904 100644
--- a/src/backend/statistics/extended_stats_funcs.c
+++ b/src/backend/statistics/extended_stats_funcs.c
@@ -1509,7 +1509,7 @@ import_pg_statistic(Relation pgsd, JsonbContainer *cont,
&nbsp; pgstup = heap_form_tuple(RelationGetDescr(pgsd), values, nulls);
&nbsp; pgstdat = heap_copy_tuple_as_datum(pgstup, RelationGetDescr(pgsd));
&nbsp;
- pfree(pgstup);
+ heap_freetuple(pgstup);
&nbsp;
&nbsp; *pg_statistic_ok = true;
&nbsp;
--

Regards,
Yonghao Lee

Attachment Content-Type Size
0001-Fix-improper-tuple-deallocation-in-import_pg_statist.patch application/octet-stream 1.4 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tomas Vondra 2026-03-05 01:01:32 Re: [PATCH] Fix improper tuple deallocation in import_pg_statist()
Previous Message Etsuro Fujita 2026-03-05 00:04:51 Re: pgsql: postgres_fdw: Inherit the local transaction's access/deferrable