@@ -57,6 +57,7 @@ typedef struct
5757typedef struct
5858{
5959DestReceiver pub ;/* publicly-known function pointers */
60+ StringInfoData buf ;/* output buffer */
6061Portal portal ;/* the Portal we are printing from */
6162bool sendDescrip ;/* send RowDescription at startup? */
6263TupleDesc attrinfo ;/* The attr info we are set up for */
@@ -127,6 +128,9 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
127128DR_printtup * myState = (DR_printtup * )self ;
128129Portal portal = myState -> portal ;
129130
131+ /* create buffer to be used for all messages */
132+ initStringInfo (& myState -> buf );
133+
130134/*
131135 * Create a temporary memory context that we can reset once per row to
132136 * recover palloc'd memory. This avoids any problems with leaks inside
@@ -302,7 +306,7 @@ printtup(TupleTableSlot *slot, DestReceiver *self)
302306TupleDesc typeinfo = slot -> tts_tupleDescriptor ;
303307DR_printtup * myState = (DR_printtup * )self ;
304308MemoryContext oldcontext ;
305- StringInfoData buf ;
309+ StringInfo buf = & myState -> buf ;
306310int natts = typeinfo -> natts ;
307311int i ;
308312
@@ -319,9 +323,9 @@ printtup(TupleTableSlot *slot, DestReceiver *self)
319323/*
320324 * Prepare a DataRow message (note buffer is in per-row context)
321325 */
322- pq_beginmessage ( & buf ,'D' );
326+ pq_beginmessage_reuse ( buf ,'D' );
323327
324- pq_sendint (& buf ,natts ,2 );
328+ pq_sendint (buf ,natts ,2 );
325329
326330/*
327331 * send the attributes of this tuple
@@ -333,7 +337,7 @@ printtup(TupleTableSlot *slot, DestReceiver *self)
333337
334338if (slot -> tts_isnull [i ])
335339{
336- pq_sendint (& buf ,-1 ,4 );
340+ pq_sendint (buf ,-1 ,4 );
337341continue ;
338342}
339343
@@ -354,21 +358,21 @@ printtup(TupleTableSlot *slot, DestReceiver *self)
354358char * outputstr ;
355359
356360outputstr = OutputFunctionCall (& thisState -> finfo ,attr );
357- pq_sendcountedtext (& buf ,outputstr ,strlen (outputstr ), false);
361+ pq_sendcountedtext (buf ,outputstr ,strlen (outputstr ), false);
358362}
359363else
360364{
361365/* Binary output */
362366bytea * outputbytes ;
363367
364368outputbytes = SendFunctionCall (& thisState -> finfo ,attr );
365- pq_sendint (& buf ,VARSIZE (outputbytes )- VARHDRSZ ,4 );
366- pq_sendbytes (& buf ,VARDATA (outputbytes ),
369+ pq_sendint (buf ,VARSIZE (outputbytes )- VARHDRSZ ,4 );
370+ pq_sendbytes (buf ,VARDATA (outputbytes ),
367371VARSIZE (outputbytes )- VARHDRSZ );
368372}
369373}
370374
371- pq_endmessage ( & buf );
375+ pq_endmessage_reuse ( buf );
372376
373377/* Return to caller's context, and flush row's temporary memory */
374378MemoryContextSwitchTo (oldcontext );
@@ -387,7 +391,7 @@ printtup_20(TupleTableSlot *slot, DestReceiver *self)
387391TupleDesc typeinfo = slot -> tts_tupleDescriptor ;
388392DR_printtup * myState = (DR_printtup * )self ;
389393MemoryContext oldcontext ;
390- StringInfoData buf ;
394+ StringInfo buf = & myState -> buf ;
391395int natts = typeinfo -> natts ;
392396int i ,
393397j ,
@@ -406,7 +410,7 @@ printtup_20(TupleTableSlot *slot, DestReceiver *self)
406410/*
407411 * tell the frontend to expect new tuple data (in ASCII style)
408412 */
409- pq_beginmessage ( & buf ,'D' );
413+ pq_beginmessage_reuse ( buf ,'D' );
410414
411415/*
412416 * send a bitmap of which attributes are not null
@@ -420,13 +424,13 @@ printtup_20(TupleTableSlot *slot, DestReceiver *self)
420424k >>=1 ;
421425if (k == 0 )/* end of byte? */
422426{
423- pq_sendint (& buf ,j ,1 );
427+ pq_sendint (buf ,j ,1 );
424428j = 0 ;
425429k = 1 <<7 ;
426430}
427431}
428432if (k != (1 <<7 ))/* flush last partial byte */
429- pq_sendint (& buf ,j ,1 );
433+ pq_sendint (buf ,j ,1 );
430434
431435/*
432436 * send the attributes of this tuple
@@ -443,10 +447,10 @@ printtup_20(TupleTableSlot *slot, DestReceiver *self)
443447Assert (thisState -> format == 0 );
444448
445449outputstr = OutputFunctionCall (& thisState -> finfo ,attr );
446- pq_sendcountedtext (& buf ,outputstr ,strlen (outputstr ), true);
450+ pq_sendcountedtext (buf ,outputstr ,strlen (outputstr ), true);
447451}
448452
449- pq_endmessage ( & buf );
453+ pq_endmessage_reuse ( buf );
450454
451455/* Return to caller's context, and flush row's temporary memory */
452456MemoryContextSwitchTo (oldcontext );
@@ -572,7 +576,7 @@ printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
572576TupleDesc typeinfo = slot -> tts_tupleDescriptor ;
573577DR_printtup * myState = (DR_printtup * )self ;
574578MemoryContext oldcontext ;
575- StringInfoData buf ;
579+ StringInfo buf = & myState -> buf ;
576580int natts = typeinfo -> natts ;
577581int i ,
578582j ,
@@ -591,7 +595,7 @@ printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
591595/*
592596 * tell the frontend to expect new tuple data (in binary style)
593597 */
594- pq_beginmessage ( & buf ,'B' );
598+ pq_beginmessage_reuse ( buf ,'B' );
595599
596600/*
597601 * send a bitmap of which attributes are not null
@@ -605,13 +609,13 @@ printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
605609k >>=1 ;
606610if (k == 0 )/* end of byte? */
607611{
608- pq_sendint (& buf ,j ,1 );
612+ pq_sendint (buf ,j ,1 );
609613j = 0 ;
610614k = 1 <<7 ;
611615}
612616}
613617if (k != (1 <<7 ))/* flush last partial byte */
614- pq_sendint (& buf ,j ,1 );
618+ pq_sendint (buf ,j ,1 );
615619
616620/*
617621 * send the attributes of this tuple
@@ -628,12 +632,12 @@ printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
628632Assert (thisState -> format == 1 );
629633
630634outputbytes = SendFunctionCall (& thisState -> finfo ,attr );
631- pq_sendint (& buf ,VARSIZE (outputbytes )- VARHDRSZ ,4 );
632- pq_sendbytes (& buf ,VARDATA (outputbytes ),
635+ pq_sendint (buf ,VARSIZE (outputbytes )- VARHDRSZ ,4 );
636+ pq_sendbytes (buf ,VARDATA (outputbytes ),
633637VARSIZE (outputbytes )- VARHDRSZ );
634638}
635639
636- pq_endmessage ( & buf );
640+ pq_endmessage_reuse ( buf );
637641
638642/* Return to caller's context, and flush row's temporary memory */
639643MemoryContextSwitchTo (oldcontext );