Skip to content

Commit f2004f1

Browse files
committed
Fix memory leak in printtup.c.
Commit f2dec34 changed things so that printtup's output stringinfo buffer was allocated outside the per-row temporary context, not inside it. This creates a need to free that buffer explicitly when the temp context is freed, but that was overlooked. In most cases, this is all happening inside a portal or executor context that will go away shortly anyhow, but that's not always true. Notably, the stringinfo ends up getting leaked when JDBC uses row-at-a-time fetches. For a query that returns wide rows, that adds up after awhile. Per bug #15700 from Matthias Otterbach. Back-patch to v11 where the faulty code was added. Discussion: https://postgr.es/m/15700-8c408321a87d56bb@postgresql.org
1 parent 11180a5 commit f2004f1

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

src/backend/access/common/printtup.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ typedef struct
6161
typedef struct
6262
{
6363
DestReceiver pub; /* publicly-known function pointers */
64-
StringInfoData buf; /* output buffer */
6564
Portal portal; /* the Portal we are printing from */
6665
bool sendDescrip; /* send RowDescription at startup? */
6766
TupleDesc attrinfo; /* The attr info we are set up for */
6867
int nattrs;
6968
PrinttupAttrInfo *myinfo; /* Cached info about each attr */
69+
StringInfoData buf; /* output buffer (*not* in tmpcontext) */
7070
MemoryContext tmpcontext; /* Memory context for per-row workspace */
7171
} DR_printtup;
7272

@@ -94,6 +94,7 @@ printtup_create_DR(CommandDest dest)
9494
self->attrinfo = NULL;
9595
self->nattrs = 0;
9696
self->myinfo = NULL;
97+
self->buf.data = NULL;
9798
self->tmpcontext = NULL;
9899

99100
return (DestReceiver *) self;
@@ -132,7 +133,10 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
132133
DR_printtup *myState = (DR_printtup *) self;
133134
Portal portal = myState->portal;
134135

135-
/* create buffer to be used for all messages */
136+
/*
137+
* Create I/O buffer to be used for all messages. This cannot be inside
138+
* tmpcontext, since we want to re-use it across rows.
139+
*/
136140
initStringInfo(&myState->buf);
137141

138142
/*
@@ -544,6 +548,10 @@ printtup_shutdown(DestReceiver *self)
544548

545549
myState->attrinfo = NULL;
546550

551+
if (myState->buf.data)
552+
pfree(myState->buf.data);
553+
myState->buf.data = NULL;
554+
547555
if (myState->tmpcontext)
548556
MemoryContextDelete(myState->tmpcontext);
549557
myState->tmpcontext = NULL;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy