@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / executor / execTuples . c , v 1.107 2009 / 06 / 11 14 : 48 : 57 momjian Exp $
* $ PostgreSQL : pgsql / src / backend / executor / execTuples . c , v 1.108 2009 / 07 / 22 17 : 00 : 20 tgl Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -95,6 +95,7 @@
# include "catalog/pg_type.h"
# include "nodes/nodeFuncs.h"
# include "storage/bufmgr.h"
# include "utils/builtins.h"
# include "utils/lsyscache.h"
# include "utils/typcache.h"
@ -1195,7 +1196,7 @@ BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
* Functions for sending tuples to the frontend ( or other specified destination )
* as though it is a SELECT result . These are used by utility commands that
* need to project directly to the destination and don ' t need or want full
* Table F unction capability . Currently used by EXPLAIN and SHOW ALL
* table f unction capability . Currently used by EXPLAIN and SHOW ALL .
*/
TupOutputState *
begin_tup_output_tupdesc ( DestReceiver * dest , TupleDesc tupdesc )
@ -1204,7 +1205,6 @@ begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
tstate = ( TupOutputState * ) palloc ( sizeof ( TupOutputState ) ) ;
tstate - > metadata = TupleDescGetAttInMetadata ( tupdesc ) ;
tstate - > slot = MakeSingleTupleTableSlot ( tupdesc ) ;
tstate - > dest = dest ;
@ -1216,17 +1216,17 @@ begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
/*
* write a single tuple
*
* values is a list of the external C string representations of the values
* to be projected .
*
* XXX This could be made more efficient , since in reality we probably only
* need a virtual tuple .
*/
void
do_tup_output ( TupOutputState * tstate , char * * values )
do_tup_output ( TupOutputState * tstate , Datum * values , bool * isnull )
{
/* build a tuple from the input strings using the tupdesc */
HeapTuple tuple = BuildTupleFromCStrings ( tstate - > metadata , values ) ;
TupleDesc tupdesc = tstate - > slot - > tts_tupleDescriptor ;
HeapTuple tuple ;
/* form a tuple */
tuple = heap_form_tuple ( tupdesc , values , isnull ) ;
/* put it in a slot */
ExecStoreTuple ( tuple , tstate - > slot , InvalidBuffer , true ) ;
@ -1241,24 +1241,34 @@ do_tup_output(TupOutputState *tstate, char **values)
/*
* write a chunk of text , breaking at newline characters
*
* NB : scribbles on its input !
*
* Should only be used with a single - TEXT - attribute tupdesc .
*/
void
do_text_output_multiline ( TupOutputState * tstate , char * text )
{
Datum values [ 1 ] ;
bool isnull [ 1 ] = { false } ;
while ( * text )
{
char * eol ;
int len ;
eol = strchr ( text , ' \n ' ) ;
if ( eol )
* eol + + = ' \0 ' ;
{
len = eol - text ;
eol + + ;
}
else
eol = text + strlen ( text ) ;
{
len = strlen ( text ) ;
eol + = len ;
}
do_tup_output ( tstate , & text ) ;
values [ 0 ] = PointerGetDatum ( cstring_to_text_with_len ( text , len ) ) ;
do_tup_output ( tstate , values , isnull ) ;
pfree ( DatumGetPointer ( values [ 0 ] ) ) ;
text = eol ;
}
}
@ -1269,6 +1279,5 @@ end_tup_output(TupOutputState *tstate)
( * tstate - > dest - > rShutdown ) ( tstate - > dest ) ;
/* note that destroying the dest is not ours to do */
ExecDropSingleTupleTableSlot ( tstate - > slot ) ;
/* XXX worth cleaning up the attinmetadata? */
pfree ( tstate ) ;
}