@@ -57,6 +57,7 @@ typedef struct
5757typedef struct
5858{
5959 DestReceiver pub ; /* publicly-known function pointers */
60+ StringInfoData buf ; /* output buffer */
6061 Portal portal ; /* the Portal we are printing from */
6162 bool sendDescrip ; /* send RowDescription at startup? */
6263 TupleDesc attrinfo ; /* The attr info we are set up for */
@@ -127,6 +128,9 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
127128 DR_printtup * myState = (DR_printtup * ) self ;
128129 Portal 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)
302306 TupleDesc typeinfo = slot -> tts_tupleDescriptor ;
303307 DR_printtup * myState = (DR_printtup * ) self ;
304308 MemoryContext oldcontext ;
305- StringInfoData buf ;
309+ StringInfo buf = & myState -> buf ;
306310 int natts = typeinfo -> natts ;
307311 int 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
334338 if (slot -> tts_isnull [i ])
335339 {
336- pq_sendint (& buf , -1 , 4 );
340+ pq_sendint (buf , -1 , 4 );
337341 continue ;
338342 }
339343
@@ -354,21 +358,21 @@ printtup(TupleTableSlot *slot, DestReceiver *self)
354358 char * outputstr ;
355359
356360 outputstr = OutputFunctionCall (& thisState -> finfo , attr );
357- pq_sendcountedtext (& buf , outputstr , strlen (outputstr ), false);
361+ pq_sendcountedtext (buf , outputstr , strlen (outputstr ), false);
358362 }
359363 else
360364 {
361365 /* Binary output */
362366 bytea * outputbytes ;
363367
364368 outputbytes = 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 ),
367371 VARSIZE (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 */
374378 MemoryContextSwitchTo (oldcontext );
@@ -387,7 +391,7 @@ printtup_20(TupleTableSlot *slot, DestReceiver *self)
387391 TupleDesc typeinfo = slot -> tts_tupleDescriptor ;
388392 DR_printtup * myState = (DR_printtup * ) self ;
389393 MemoryContext oldcontext ;
390- StringInfoData buf ;
394+ StringInfo buf = & myState -> buf ;
391395 int natts = typeinfo -> natts ;
392396 int i ,
393397 j ,
@@ -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)
420424 k >>= 1 ;
421425 if (k == 0 ) /* end of byte? */
422426 {
423- pq_sendint (& buf , j , 1 );
427+ pq_sendint (buf , j , 1 );
424428 j = 0 ;
425429 k = 1 << 7 ;
426430 }
427431 }
428432 if (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)
443447 Assert (thisState -> format == 0 );
444448
445449 outputstr = 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 */
452456 MemoryContextSwitchTo (oldcontext );
@@ -572,7 +576,7 @@ printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
572576 TupleDesc typeinfo = slot -> tts_tupleDescriptor ;
573577 DR_printtup * myState = (DR_printtup * ) self ;
574578 MemoryContext oldcontext ;
575- StringInfoData buf ;
579+ StringInfo buf = & myState -> buf ;
576580 int natts = typeinfo -> natts ;
577581 int i ,
578582 j ,
@@ -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)
605609 k >>= 1 ;
606610 if (k == 0 ) /* end of byte? */
607611 {
608- pq_sendint (& buf , j , 1 );
612+ pq_sendint (buf , j , 1 );
609613 j = 0 ;
610614 k = 1 << 7 ;
611615 }
612616 }
613617 if (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)
628632 Assert (thisState -> format == 1 );
629633
630634 outputbytes = 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 ),
633637 VARSIZE (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 */
639643 MemoryContextSwitchTo (oldcontext );
0 commit comments